panic in usb_transfer_complete in vmware

Matthew Dillon dillon at apollo.backplane.com
Tue Jun 27 15:27:43 PDT 2006


:...
:> just tried booting 1.4 (snaphot) in vmware.  it works normally, but if I 
:> have my usb stick passed through to dragonfly, it panics like below (I 
:> think that's the same panic sascha is seeing).
:> 
:> A little bit playing with ddb showed that pipe->queue is empty.
:
:Dump is in ~swildner/crash on leaf.
:
:Sascha

    There is some sort of recursion happening but I'm not sure whether
    the recursion is valid or whether it is itself a bug.  The crash is
    occuring while usb_transfer_complete() is operating on the wrong 'xfer'
    structure.

    I'm going to make a semi-wild guess.  Look at the LIST_FOREACH() on
    line 1274 in /usr/src/sys/bus/usb/uhci.c ... I think the 'ii' structure
    could be getting ripped out from under the list scanner.

    I've included a bad hack for you to try to see if it solves the problem.

					-Matt
					Matthew Dillon 
					<dillon at xxxxxxxxxxxxx>

Index: bus/usb/uhci.c
===================================================================
RCS file: /cvs/src/sys/bus/usb/uhci.c,v
retrieving revision 1.13
diff -u -r1.13 uhci.c
--- bus/usb/uhci.c	29 Apr 2006 22:05:21 -0000	1.13
+++ bus/usb/uhci.c	27 Jun 2006 21:14:27 -0000
@@ -386,6 +386,7 @@
 	LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list)
 #define uhci_del_intr_info(ii) \
 	do { \
+		++ii->sc->sc_intrhead_deletion_counter; \
 		LIST_REMOVE((ii), list); \
 		(ii)->list.le_prev = NULL; \
 	} while (0)
@@ -1254,6 +1255,7 @@
 {
 	uhci_softc_t *sc = v;
 	uhci_intr_info_t *ii;
+	int last_deletion_counter;
 
 	DPRINTFN(10,("%s: uhci_softintr (%d)\n", USBDEVNAME(sc->sc_bus.bdev),
 		     sc->sc_bus.intr_context));
@@ -1270,9 +1272,17 @@
 	 * output on a slow console).
 	 * We scan all interrupt descriptors to see if any have
 	 * completed.
+	 *
+	 * XXX horrible hack - use a counter to detect if  the list is
+	 * modified out from under us and rescan if it is.
 	 */
-	LIST_FOREACH(ii, &sc->sc_intrhead, list)
+again:
+	last_deletion_counter = sc->sc_intrhead_deletion_counter;
+	LIST_FOREACH(ii, &sc->sc_intrhead, list) {
 		uhci_check_intr(sc, ii);
+		if (sc->sc_intrhead_deletion_counter != last_deletion_counter)
+			goto again;
+	}
 
 #ifdef USB_USE_SOFTINTR
 	if (sc->sc_softwake) {
Index: bus/usb/uhcivar.h
===================================================================
RCS file: /cvs/src/sys/bus/usb/uhcivar.h,v
retrieving revision 1.4
diff -u -r1.4 uhcivar.h
--- bus/usb/uhcivar.h	11 Feb 2004 15:17:26 -0000	1.4
+++ bus/usb/uhcivar.h	27 Jun 2006 21:10:30 -0000
@@ -179,6 +179,7 @@
 	char sc_dying;
 
 	LIST_HEAD(, uhci_intr_info) sc_intrhead;
+	int  sc_intrhead_deletion_counter;
 
 	/* Info for the root hub interrupt channel. */
 	int sc_ival;			/* time between root hub intrs */





More information about the Bugs mailing list