public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] async: make sure independent async domains can't accidentally entangle.
@ 2009-05-24 14:29 James Bottomley
  2009-05-24 18:50 ` James Bottomley
  0 siblings, 1 reply; 3+ messages in thread
From: James Bottomley @ 2009-05-24 14:29 UTC (permalink / raw)
  To: Arjan van de Ven; +Cc: linux-scsi, linux-kernel

The problem occurs when async_synchronize_full_domain() is called when
the async_pending list is not empty.  This will cause lowest_running()
to return the cookie of the first entry on the async_pending list, which
might be nothing at all to do with the domain being asked for and thus
cause the domain synchronization to wait for an unrelated domain.   This
can cause a deadlock if domain synchronization is used from one domain
to wait for another.

Fix by running over the async_pending list to see if any pending items
actually belong to our domain (and return their cookies if they do).

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

---

diff --git a/kernel/async.c b/kernel/async.c
index 968ef94..9b01c61 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -92,19 +92,24 @@ extern int initcall_debug;
 static async_cookie_t  __lowest_in_progress(struct list_head *running)
 {
 	struct async_entry *entry;
+	unsigned long flags;
+	async_cookie_t ret = next_cookie; /* begin with "infinity" value */
+
 	if (!list_empty(running)) {
 		entry = list_first_entry(running,
 			struct async_entry, list);
-		return entry->cookie;
+		ret = entry->cookie;
 	} else if (!list_empty(&async_pending)) {
-		entry = list_first_entry(&async_pending,
-			struct async_entry, list);
-		return entry->cookie;
-	} else {
-		/* nothing in progress... next_cookie is "infinity" */
-		return next_cookie;
+		spin_lock_irqsave(&async_lock, flags);
+		list_for_each_entry(entry, &async_pending, list)
+			if (entry->running == running) {
+				ret = entry->cookie;
+				break;
+			}
+		spin_unlock_irqrestore(&async_lock, flags);
 	}
 
+	return ret;
 }
 
 static async_cookie_t  lowest_in_progress(struct list_head *running)



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] async: make sure independent async domains can't accidentally entangle.
  2009-05-24 14:29 [PATCH] async: make sure independent async domains can't accidentally entangle James Bottomley
@ 2009-05-24 18:50 ` James Bottomley
  2009-05-24 19:40   ` Arjan van de Ven
  0 siblings, 1 reply; 3+ messages in thread
From: James Bottomley @ 2009-05-24 18:50 UTC (permalink / raw)
  To: Arjan van de Ven; +Cc: linux-scsi, linux-kernel

On Sun, 2009-05-24 at 09:29 -0500, James Bottomley wrote:
> The problem occurs when async_synchronize_full_domain() is called when
> the async_pending list is not empty.  This will cause lowest_running()
> to return the cookie of the first entry on the async_pending list, which
> might be nothing at all to do with the domain being asked for and thus
> cause the domain synchronization to wait for an unrelated domain.   This
> can cause a deadlock if domain synchronization is used from one domain
> to wait for another.
> 
> Fix by running over the async_pending list to see if any pending items
> actually belong to our domain (and return their cookies if they do).
> 
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

OK, so that version locked up under testing ... this version doesn't ---
I think the phrase "MUST be called with the lock held!" was supposed to
be some sort of clue ...

James

---

diff --git a/kernel/async.c b/kernel/async.c
index 968ef94..13ed571 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -92,19 +92,21 @@ extern int initcall_debug;
 static async_cookie_t  __lowest_in_progress(struct list_head *running)
 {
 	struct async_entry *entry;
+	async_cookie_t ret = next_cookie; /* begin with "infinity" value */
+
 	if (!list_empty(running)) {
 		entry = list_first_entry(running,
 			struct async_entry, list);
-		return entry->cookie;
+		ret = entry->cookie;
 	} else if (!list_empty(&async_pending)) {
-		entry = list_first_entry(&async_pending,
-			struct async_entry, list);
-		return entry->cookie;
-	} else {
-		/* nothing in progress... next_cookie is "infinity" */
-		return next_cookie;
+		list_for_each_entry(entry, &async_pending, list)
+			if (entry->running == running) {
+				ret = entry->cookie;
+				break;
+			}
 	}
 
+	return ret;
 }
 
 static async_cookie_t  lowest_in_progress(struct list_head *running)



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] async: make sure independent async domains can't accidentally entangle.
  2009-05-24 18:50 ` James Bottomley
@ 2009-05-24 19:40   ` Arjan van de Ven
  0 siblings, 0 replies; 3+ messages in thread
From: Arjan van de Ven @ 2009-05-24 19:40 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi, linux-kernel

On Sun, 24 May 2009 13:50:43 -0500
James Bottomley <James.Bottomley@HansenPartnership.com> wrote:

> On Sun, 2009-05-24 at 09:29 -0500, James Bottomley wrote:
> > The problem occurs when async_synchronize_full_domain() is called
> > when the async_pending list is not empty.  This will cause
> > lowest_running() to return the cookie of the first entry on the
> > async_pending list, which might be nothing at all to do with the
> > domain being asked for and thus cause the domain synchronization to
> > wait for an unrelated domain.   This can cause a deadlock if domain
> > synchronization is used from one domain to wait for another.
> > 
> > Fix by running over the async_pending list to see if any pending
> > items actually belong to our domain (and return their cookies if
> > they do).
> > 
> > Signed-off-by: James Bottomley
> > <James.Bottomley@HansenPartnership.com>
> 
> OK, so that version locked up under testing ... this version doesn't
> --- I think the phrase "MUST be called with the lock held!" was
> supposed to be some sort of clue ...

there's not many comments there.. but the ones that exist do mean
something ;-)

I'll craft this patch into your original description and send it to
Linus to see if he'll take it for .30, otherwise it'll go for .31


-- 
Arjan van de Ven 	Intel Open Source Technology Centre
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-05-24 20:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-24 14:29 [PATCH] async: make sure independent async domains can't accidentally entangle James Bottomley
2009-05-24 18:50 ` James Bottomley
2009-05-24 19:40   ` Arjan van de Ven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox