]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/0004-md-fix-deadlock-when-stopping-arrays.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / 0004-md-fix-deadlock-when-stopping-arrays.patch
1 From 5fd3a17ed456637a224cf4ca82b9ad9d005bc8d4 Mon Sep 17 00:00:00 2001
2 From: Dan Williams <dan.j.williams@intel.com>
3 Date: Wed, 4 Mar 2009 00:57:25 -0700
4 Subject: [PATCH] md: fix deadlock when stopping arrays
5
6 Resolve a deadlock when stopping redundant arrays, i.e. ones that
7 require a call to sysfs_remove_group when shutdown. The deadlock is
8 summarized below:
9
10 Thread1 Thread2
11 ------- -------
12 read sysfs attribute stop array
13 take mddev lock
14 sysfs_remove_group
15 sysfs_get_active
16 wait for mddev lock
17 wait for active
18
19 Sysrq-w:
20 --------
21 mdmon S 00000017 2212 4163 1
22 f1982ea8 00000046 2dcf6b85 00000017 c0b23100 f2f83ed0 c0b23100 f2f8413c
23 c0b23100 c0b23100 c0b1fb98 f2f8413c 00000000 f2f8413c c0b23100 f2291ecc
24 00000002 c0b23100 00000000 00000017 f2f83ed0 f1982eac 00000046 c044d9dd
25 Call Trace:
26 [<c044d9dd>] ? debug_mutex_add_waiter+0x1d/0x58
27 [<c06ef451>] __mutex_lock_common+0x1d9/0x338
28 [<c06ef451>] ? __mutex_lock_common+0x1d9/0x338
29 [<c06ef5e3>] mutex_lock_interruptible_nested+0x33/0x3a
30 [<c0634553>] ? mddev_lock+0x14/0x16
31 [<c0634553>] mddev_lock+0x14/0x16
32 [<c0634eda>] md_attr_show+0x2a/0x49
33 [<c04e9997>] sysfs_read_file+0x93/0xf9
34 mdadm D 00000017 2812 4177 1
35 f0401d78 00000046 430456f8 00000017 f0401d58 f0401d20 c0b23100 f2da2c4c
36 c0b23100 c0b23100 c0b1fb98 f2da2c4c 0a10fc36 00000000 c0b23100 f0401d70
37 00000003 c0b23100 00000000 00000017 f2da29e0 00000001 00000002 00000000
38 Call Trace:
39 [<c06eed1b>] schedule_timeout+0x1b/0x95
40 [<c06eed1b>] ? schedule_timeout+0x1b/0x95
41 [<c06eeb97>] ? wait_for_common+0x34/0xdc
42 [<c044fa8a>] ? trace_hardirqs_on_caller+0x18/0x145
43 [<c044fbc2>] ? trace_hardirqs_on+0xb/0xd
44 [<c06eec03>] wait_for_common+0xa0/0xdc
45 [<c0428c7c>] ? default_wake_function+0x0/0x12
46 [<c06eeccc>] wait_for_completion+0x17/0x19
47 [<c04ea620>] sysfs_addrm_finish+0x19f/0x1d1
48 [<c04e920e>] sysfs_hash_and_remove+0x42/0x55
49 [<c04eb4db>] sysfs_remove_group+0x57/0x86
50 [<c0638086>] do_md_stop+0x13a/0x499
51
52 This has been there for a while, but is easier to trigger now that mdmon
53 is closely watching sysfs.
54
55 Cc: <stable@kernel.org>
56 Reported-by: Jacek Danecki <jacek.danecki@intel.com>
57 Signed-off-by: Dan Williams <dan.j.williams@intel.com>
58 Acked-by: NeilBrown <neilb@suse.de>
59 ---
60 drivers/md/md.c | 10 +++++++---
61 1 file changed, 7 insertions(+), 3 deletions(-)
62
63 --- a/drivers/md/md.c
64 +++ b/drivers/md/md.c
65 @@ -305,9 +305,14 @@ static inline int mddev_trylock(mddev_t
66 return mutex_trylock(&mddev->reconfig_mutex);
67 }
68
69 +static struct attribute_group md_redundancy_group;
70 static inline void mddev_unlock(mddev_t * mddev)
71 {
72 mutex_unlock(&mddev->reconfig_mutex);
73 + if (unlikely(mddev->private == &md_redundancy_group)) {
74 + sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
75 + mddev->private = NULL;
76 + }
77
78 md_wakeup_thread(mddev->thread);
79 }
80 @@ -3903,10 +3908,9 @@ static int do_md_stop(mddev_t * mddev, i
81 mddev->queue->merge_bvec_fn = NULL;
82 mddev->queue->unplug_fn = NULL;
83 mddev->queue->backing_dev_info.congested_fn = NULL;
84 - if (mddev->pers->sync_request)
85 - sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
86 -
87 module_put(mddev->pers->owner);
88 + if (mddev->pers->sync_request)
89 + mddev->private = &md_redundancy_group;
90 mddev->pers = NULL;
91 /* tell userspace to handle 'inactive' */
92 sysfs_notify(&mddev->kobj, NULL, "array_state");