summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-11-27 12:14:40 +1100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-10 11:13:11 -0800
commit90a4ff3cb2c88d33c737f99437341338af0637be (patch)
tree487502f99891468fbf3e911cdb8eb90dcc932106
parente9e577813a5a85c9315ed7c1c74c0652a28637ae (diff)
md/raid1{,0}: fix deadlock in bitmap_unplug.
commit 874807a83139abc094f939e93623c5623573d543 upstream. If the raid1 or raid10 unplug function gets called from a make_request function (which is very possible) when there are bios on the current->bio_list list, then it will not be able to successfully call bitmap_unplug() and it could need to submit more bios and wait for them to complete. But they won't complete while current->bio_list is non-empty. So detect that case and handle the unplugging off to another thread just like we already do when called from within the scheduler. RAID1 version of bug was introduced in 3.6, so that part of fix is suitable for 3.6.y. RAID10 part won't apply. Reported-by: Torsten Kaiser <just.for.lkml@googlemail.com> Reported-by: Peter Maloney <peter.maloney@brockmann-consult.de> Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/md/raid1.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 05bb49e13648..7077dcf47185 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -958,7 +958,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
struct r1conf *conf = mddev->private;
struct bio *bio;
- if (from_schedule) {
+ if (from_schedule || current->bio_list) {
spin_lock_irq(&conf->device_lock);
bio_list_merge(&conf->pending_bio_list, &plug->pending);
conf->pending_count += plug->pending_cnt;