Files
linux/include/linux
Miklos Szeredi 8039a47e67 fix shrink_dcache_parent() livelock
commit eaf5f90735 upstream.

Two (or more) concurrent calls of shrink_dcache_parent() on the same dentry may
cause shrink_dcache_parent() to loop forever.

Here's what appears to happen:

1 - CPU0: select_parent(P) finds C and puts it on dispose list, returns 1

2 - CPU1: select_parent(P) locks P->d_lock

3 - CPU0: shrink_dentry_list() locks C->d_lock
   dentry_kill(C) tries to lock P->d_lock but fails, unlocks C->d_lock

4 - CPU1: select_parent(P) locks C->d_lock,
         moves C from dispose list being processed on CPU0 to the new
dispose list, returns 1

5 - CPU0: shrink_dentry_list() finds dispose list empty, returns

6 - Goto 2 with CPU0 and CPU1 switched

Basically select_parent() steals the dentry from shrink_dentry_list() and thinks
it found a new one, causing shrink_dentry_list() to think it's making progress
and loop over and over.

One way to trigger this is to make udev calls stat() on the sysfs file while it
is going away.

Having a file in /lib/udev/rules.d/ with only this one rule seems to the trick:

ATTR{vendor}=="0x8086", ATTR{device}=="0x10ca", ENV{PCI_SLOT_NAME}="%k", ENV{MATCHADDR}="$attr{address}", RUN+="/bin/true"

Then execute the following loop:

while true; do
        echo -bond0 > /sys/class/net/bonding_masters
        echo +bond0 > /sys/class/net/bonding_masters
        echo -bond1 > /sys/class/net/bonding_masters
        echo +bond1 > /sys/class/net/bonding_masters
done

One fix would be to check all callers and prevent concurrent calls to
shrink_dcache_parent().  But I think a better solution is to stop the
stealing behavior.

This patch adds a new dentry flag that is set when the dentry is added to the
dispose list.  The flag is cleared in dentry_lru_del() in case the dentry gets a
new reference just before being pruned.

If the dentry has this flag, select_parent() will skip it and let
shrink_dentry_list() retry pruning it.  With select_parent() skipping those
dentries there will not be the appearance of progress (new dentries found) when
there is none, hence shrink_dcache_parent() will not loop forever.

Set the flag is also set in prune_dcache_sb() for consistency as suggested by
Linus.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2012-01-25 17:24:51 -08:00
..
2011-05-04 14:08:36 -07:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-06-01 11:36:49 +01:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2012-01-12 11:35:33 -08:00
2011-03-31 11:26:23 -03:00
2010-03-12 15:53:10 -08:00
2011-02-24 19:58:42 +01:00
2010-10-15 21:18:59 +02:00
2011-04-01 02:24:31 -04:00
2009-06-17 00:36:36 -04:00
2010-11-23 20:14:46 +00:00
2009-01-30 23:38:03 +05:30
2010-05-27 09:12:53 -07:00
2009-09-08 17:42:50 -07:00
2011-01-31 14:03:00 -08:00
2011-05-28 17:41:46 +02:00
2009-04-01 08:59:23 -07:00
2011-01-15 20:07:45 -05:00
2011-03-10 08:52:07 +01:00
2011-03-22 17:43:59 -07:00
2011-03-11 14:25:50 +00:00
2009-01-30 23:40:06 +05:30
2009-01-04 13:33:20 -08:00
2010-06-24 21:30:09 -07:00
2009-11-20 20:13:39 +01:00
2009-11-20 20:13:39 +01:00
2009-11-20 20:13:39 +01:00
2011-03-31 11:26:23 -03:00
2010-12-16 17:53:38 +01:00
2011-03-31 11:26:23 -03:00
2011-05-26 17:12:34 -07:00
2011-05-26 17:12:34 -07:00
2011-03-31 11:26:23 -03:00
2010-10-25 08:02:40 -07:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-22 17:44:15 -07:00
2011-05-19 15:59:38 -07:00
2012-01-25 17:24:51 -08:00
2011-01-10 08:51:44 -08:00
2010-05-19 22:41:57 -04:00
2010-08-04 11:00:45 +02:00
2011-06-27 16:06:19 -07:00
2011-05-23 10:47:06 -05:00
2009-12-10 23:52:01 +00:00
2011-05-29 13:03:09 +01:00
2011-03-31 11:26:23 -03:00
2009-11-04 09:50:58 -08:00
2011-03-10 11:35:17 +01:00
2011-05-24 10:21:29 +02:00
2011-05-24 10:21:29 +02:00
2009-09-14 17:41:42 -07:00
2010-10-21 14:47:59 +02:00
2009-01-30 23:46:40 +05:30
2009-11-04 09:50:58 -08:00
2011-06-09 15:05:48 -07:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2009-12-23 13:33:54 +01:00
2011-01-12 20:16:43 -05:00
2011-03-14 19:12:20 -04:00
2010-08-19 17:18:03 -07:00
2011-01-10 08:51:44 -08:00
2011-01-07 17:50:27 +11:00
2011-01-07 17:50:23 +11:00
2010-12-07 20:16:56 +01:00
2009-06-18 13:04:05 -07:00
2009-11-04 09:50:58 -08:00
2010-10-25 14:11:37 -07:00
2010-05-21 09:34:29 -07:00
2011-03-05 10:56:00 +01:00
2009-09-01 01:13:31 -07:00
2011-03-31 11:26:23 -03:00
2010-02-09 11:13:56 +01:00
2011-03-31 11:26:23 -03:00
2011-06-27 16:06:19 -07:00
2010-03-07 22:17:09 +01:00
2010-10-12 16:53:37 +02:00
2011-05-26 12:03:50 -07:00
2010-03-02 12:23:42 +01:00
2011-02-23 00:53:26 +00:00
2011-05-25 20:43:32 +02:00
2011-03-31 11:26:23 -03:00
2011-05-08 16:41:45 -07:00
2009-11-04 09:50:58 -08:00
2009-11-04 09:50:58 -08:00
2009-11-04 09:50:58 -08:00
2009-11-04 09:50:58 -08:00
2009-01-30 23:53:12 +05:30
2010-06-03 03:21:52 -07:00
2010-11-16 10:58:30 -08:00
2009-11-04 09:50:58 -08:00
2010-09-21 18:04:47 -07:00
2009-01-30 23:56:13 +05:30
2009-01-30 23:56:48 +05:30
2010-08-19 17:16:23 -07:00
2010-08-09 20:45:05 -07:00
2009-09-26 10:17:19 -07:00
2009-04-21 13:41:48 -07:00
2011-05-26 17:12:37 -07:00
2011-03-31 11:26:23 -03:00
2010-11-24 11:16:42 -08:00
2009-01-30 23:59:44 +05:30
2009-01-31 00:00:06 +05:30
2010-10-07 14:08:55 +01:00
2010-06-03 03:21:52 -07:00
2011-03-31 11:26:23 -03:00
2010-08-10 11:49:21 -07:00
2010-12-09 20:17:07 -08:00
2010-08-12 11:27:58 +02:00
2011-02-17 11:12:40 -08:00
2010-10-22 15:34:12 -05:00
2011-01-13 17:32:31 -08:00
2011-01-13 17:32:47 -08:00
2011-02-13 16:54:24 -08:00
2011-01-24 14:45:11 +10:30
2010-09-09 18:57:24 -07:00
2011-03-31 11:26:23 -03:00
2011-05-22 08:47:53 -04:00
2010-04-03 14:56:05 -07:00
2011-03-31 11:26:23 -03:00
2009-04-06 16:06:26 +01:00
2009-07-30 16:03:45 +09:30
2011-05-19 20:50:53 -04:00
2011-05-24 14:33:35 +02:00
2011-04-25 18:14:10 -07:00
2009-12-26 20:40:34 -08:00
2009-04-28 07:37:28 +02:00
2009-06-16 19:47:48 -07:00
2010-12-06 11:03:46 -08:00
2009-09-22 07:17:35 -07:00
2009-06-16 08:40:20 +02:00
2009-04-29 17:32:35 -07:00
2009-01-31 00:00:35 +05:30
2010-06-03 03:21:52 -07:00
2011-11-11 09:36:29 -08:00
2011-11-11 09:36:48 -08:00
2011-05-19 16:55:27 +09:30
2011-01-16 13:47:07 -05:00
2011-03-31 11:26:23 -03:00
2010-02-10 23:49:08 +09:00
2010-10-12 16:53:34 +02:00
2009-11-04 09:50:58 -08:00
2011-05-20 11:46:11 -07:00
2009-06-17 18:02:11 -07:00
2009-06-17 18:02:11 -07:00
2009-06-15 21:44:43 -07:00
2011-05-26 17:12:34 -07:00
2010-07-05 16:14:52 -06:00
2011-04-20 17:01:19 +10:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2009-04-01 08:59:13 -07:00
2009-04-01 08:59:13 -07:00
2011-01-16 13:47:07 -05:00
2012-01-25 17:24:38 -08:00
2011-05-26 17:12:37 -07:00
2010-08-21 23:40:14 -07:00
2011-03-11 15:13:26 -05:00
2010-07-19 01:58:48 +02:00
2011-03-31 11:26:23 -03:00
2011-05-24 12:10:51 +02:00
2010-08-04 21:53:17 -07:00
2011-01-13 08:03:21 -08:00
2009-12-02 09:55:33 +01:00
2011-03-31 11:26:23 -03:00
2011-05-13 16:31:00 -07:00
2009-03-30 15:22:01 +02:00
2011-03-31 11:26:23 -03:00
2009-06-11 21:36:12 -04:00
2010-10-29 04:16:31 -04:00
2010-02-10 17:47:17 -08:00
2011-01-14 02:36:43 +00:00
2011-05-05 23:16:59 -07:00
2010-09-08 18:16:55 -07:00
2010-03-12 15:52:44 -08:00
2010-08-09 16:47:27 -04:00
2011-03-31 11:26:23 -03:00
2010-11-15 13:24:06 -05:00
2011-05-25 08:39:19 -07:00
2009-11-04 09:50:58 -08:00
2010-05-11 10:09:47 +02:00
2011-10-03 11:40:08 -07:00
2010-03-12 15:53:10 -08:00
2011-10-16 14:14:51 -07:00
2010-06-03 03:21:52 -07:00
2010-10-30 12:12:50 +02:00
2009-04-08 14:33:38 -07:00
2011-12-09 08:52:39 -08:00
2011-03-31 11:26:23 -03:00
2011-05-05 11:10:14 -07:00
2009-01-31 00:07:00 +05:30
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2010-08-09 16:48:44 -04:00
2011-06-27 18:00:12 -07:00
2010-08-30 13:23:33 -07:00
2011-02-28 18:00:31 -08:00
2010-03-25 17:18:43 -07:00
2011-02-02 15:28:18 +01:00
2011-06-15 20:03:59 -07:00
2010-11-29 08:55:25 +11:00
2010-11-29 08:55:22 +11:00
2011-10-03 11:39:49 -07:00
2011-11-11 09:35:12 -08:00
2011-03-31 11:26:23 -03:00
2009-11-10 20:54:38 -08:00
2010-12-20 09:37:33 +01:00
2011-06-07 09:05:42 -07:00
2012-01-12 11:35:25 -08:00
2010-05-19 22:40:47 -04:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-05-30 11:14:16 +09:30
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-01-13 08:03:24 -08:00
2010-04-06 20:35:58 +04:00