1 From: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
2 Subject: dm: Fix lock dependency warning for request based dm
5 > > From: Christof Schmitt <christof.schmitt@de.ibm.com>
7 > > Testing with request based dm multipathing and lock dependency checking
8 > > revealed this problem. Fix this by disabling interrupts when acquiring the
9 > > map_lock from the ioctl call in __bind and __unbind.
11 > > It seems that the problem has been introduced with this patch:
12 > > http://lkml.indiana.edu/hypermail/linux/kernel/0810.0/1067.html
14 Thank you for your testing request-based dm-multipath and the patch.
16 Attached is a patch to fix it.
17 Since request-based dm gets map_lock after taking queue_lock with
18 interrupt disabled, we have to use save/restore variant.
19 (By the way, although lockdep warns the deadlock possibility, currently
20 there should be no such code path in request-based dm where request_fn
21 is called from the interrupt context.)
23 I have done simple build and boot testings, but haven't done other
24 testings (e.g. stress testing) yet.
25 I will include this patch to the next update after such testings.
30 Signed-off-by: Nikanth karthikesan <knikanth@suse.de>
32 Index: linux-2.6.27-SLE11_BRANCH/drivers/md/dm.c
33 ===================================================================
34 --- linux-2.6.27-SLE11_BRANCH.orig/drivers/md/dm.c
35 +++ linux-2.6.27-SLE11_BRANCH/drivers/md/dm.c
36 @@ -525,12 +525,13 @@ static int queue_io(struct mapped_device
37 struct dm_table *dm_get_table(struct mapped_device *md)
40 + unsigned long flags;
42 - read_lock(&md->map_lock);
43 + read_lock_irqsave(&md->map_lock, flags);
47 - read_unlock(&md->map_lock);
48 + read_unlock_irqrestore(&md->map_lock, flags);
52 @@ -1913,6 +1914,7 @@ static int __bind(struct mapped_device *
54 struct request_queue *q = md->queue;
56 + unsigned long flags;
58 size = dm_table_get_size(t);
60 @@ -1942,7 +1944,7 @@ static int __bind(struct mapped_device *
61 if (dm_table_request_based(t) && !blk_queue_stopped(q))
64 - write_lock(&md->map_lock);
65 + write_lock_irqsave(&md->map_lock, flags);
67 dm_table_set_restrictions(t, q);
68 dm_table_set_integrity(t, md);
69 @@ -1951,7 +1953,7 @@ static int __bind(struct mapped_device *
71 set_disk_ro(md->disk, 0);
73 - write_unlock(&md->map_lock);
74 + write_unlock_irqrestore(&md->map_lock, flags);
78 @@ -1959,14 +1961,15 @@ static int __bind(struct mapped_device *
79 static void __unbind(struct mapped_device *md)
81 struct dm_table *map = md->map;
82 + unsigned long flags;
87 dm_table_event_callback(map, NULL, NULL);
88 - write_lock(&md->map_lock);
89 + write_lock_irqsave(&md->map_lock, flags);
91 - write_unlock(&md->map_lock);
92 + write_unlock_irqrestore(&md->map_lock, flags);
93 dm_table_destroy(map);