Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1745

kernel-2.6.18-238.el5.src.rpm

From: Jonathan Brassow <jbrassow@redhat.com>
Date: Mon, 17 Dec 2007 16:17:29 -0600
Subject: [md] dm-mirror: write_callback might deadlock
Message-id: 1197929849.28090.16.camel@hydrogen
O-Subject: [RHEL 5.2 PATCH] dm-mirror: spinlock in write_callback has the potential for deadlock
Bugzilla: 247877

Bug #247877:

write_callback is in dm-raid1.c is called when an I/O completes.  It
calls spin_lock(&ms->lock).  Since write_callback could be called from
either process or interrupt context, we need to use spin_lock_irqsave().

 brassow

Acked-by: Alasdair G Kergon <agk@redhat.com>

diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index b22ab8f..9810fe3 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1063,6 +1063,7 @@ static void write_callback(unsigned long error, void *context)
 	struct mirror_set *ms;
 	int uptodate = 0;
 	int should_wake = 0;
+	unsigned long flags;
 
 	ms = (bio_get_m(bio))->ms;
 	bio_set_m(bio, NULL);
@@ -1087,11 +1088,11 @@ static void write_callback(unsigned long error, void *context)
 			 * events can block, we need to do it in
 			 * the main thread.
 			 */
-			spin_lock(&ms->lock);
+			spin_lock_irqsave(&ms->lock, flags);
 			if (!ms->failures.head)
 				should_wake = 1;
 			bio_list_add(&ms->failures, bio);
-			spin_unlock(&ms->lock);
+			spin_unlock_irqrestore(&ms->lock, flags);
 			if (should_wake)
 				wake(ms);
 			return;