<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">ChangeSet 1.1238, 2003/06/18 16:54:00-07:00, david-b@pacbell.net

[PATCH] USB: SMP ehci-q.c 1010 BUG()

Stefano Barbato wrote:
&gt; Dual PIII
&gt; kernel 2.4.21-rc2 (w/ SMP)  (2.5.69 below)
&gt; ...
&gt;
&gt; I put a few printk before the BUG() and I found that the offending if() is
&gt; this:
&gt;         if(qh-&gt;qh_state != QH_STATE_LINKED
&gt;                                 &amp;&amp; qh-&gt;qh_state != QH_STATE_UNLINK_WAIT)
&gt;
&gt; because qh_state were QH_STATE_COMPLETING.

I got a similar SMP report recently, but without info about
which clause was failing -- which is a key clue, thanks!!

The COMPLETING state is used only while a QH is being
scanned for completed TDs.  (Think CPU-0 irq handler.)
Looking at the handful of places that call the routine
reporting the BUG(), a couple seem like they could make
trouble with multiple CPUs in the driver.


 drivers/usb/host/ehci-q.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)


diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	Wed Jun 18 17:35:29 2003
+++ b/drivers/usb/host/ehci-q.c	Wed Jun 18 17:35:29 2003
@@ -958,11 +958,11 @@
 	qh-&gt;qh_state = QH_STATE_IDLE;
 	qh-&gt;qh_next.qh = 0;
 	qh_put (ehci, qh);			// refcount from reclaim 
-	ehci-&gt;reclaim = 0;
-	ehci-&gt;reclaim_ready = 0;
 
 	/* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */
 	next = qh-&gt;reclaim;
+	ehci-&gt;reclaim = next;
+	ehci-&gt;reclaim_ready = 0;
 	qh-&gt;reclaim = 0;
 
 	qh_completions (ehci, qh, regs);
@@ -981,8 +981,10 @@
 			timer_action (ehci, TIMER_ASYNC_OFF);
 	}
 
-	if (next)
+	if (next) {
+		ehci-&gt;reclaim = 0;
 		start_unlink_async (ehci, next);
+	}
 }
 
 /* makes sure the async qh will become idle */
@@ -1086,7 +1088,8 @@
 			if (list_empty (&amp;qh-&gt;qtd_list)) {
 				if (qh-&gt;stamp == ehci-&gt;stamp)
 					action = TIMER_ASYNC_SHRINK;
-				else if (!ehci-&gt;reclaim)
+				else if (!ehci-&gt;reclaim
+					    &amp;&amp; qh-&gt;qh_state == QH_STATE_LINKED)
 					start_unlink_async (ehci, qh);
 			}
 
</pre></body></html>