Hi, On Fri, 1 Mar 2013 13:43:00 +0000 "Wade, Daniel" <dw...@meridium.com> wrote: > -----Original Message----- > From: owner-t...@openbsd.org [mailto:owner-t...@openbsd.org] On Behalf Of > Stefan Sperling > Sent: Thursday, February 28, 2013 12:16 PM > To: Edd Barrett > Cc: tech@openbsd.org > Subject: Re: Wake from zzz causes panic on thinkpad x60 > > On Thu, Feb 28, 2013 at 04:59:12PM +0000, Edd Barrett wrote: >> Went to run some TESTS for release and I am seeing panics when waking >> my thinkpad x60 from zzz. >> >> I didn't have a serial line attached to get trace and ps, so I have >> taken pictures of the kernel debugger. Sorry about that. >> >> http://farm9.staticflickr.com/8505/8516467142_1f3580e87a_c.jpg > > I've seen this panic in usb_abort_task_thread() on an x60s before. > It doesn't happen often. It's not a new issue in recent snaps.
Same problem happens on my sony vaio vgn-sz94s. Attached diff will fix the problem. Remove `abort_task' from usb task queue before recycling a `struct usbd_xfer object' which includes the `abort_task'. Otherwise usb_abort_task_thread() may try to dequeue the recycled task then it causes panic with page fault. test, comment or ok? Index: sys/dev/usb/ehci.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ehci.c,v retrieving revision 1.131 diff -u -p -r1.131 ehci.c --- sys/dev/usb/ehci.c 19 Apr 2013 08:58:53 -0000 1.131 +++ sys/dev/usb/ehci.c 17 May 2013 08:37:12 -0000 @@ -1204,6 +1204,7 @@ void ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { struct ehci_softc *sc = (struct ehci_softc *)bus; + struct usb_task *task = &EXFER(xfer)->abort_task; #ifdef DIAGNOSTIC if (xfer->busy_free != XFER_BUSY) { @@ -1217,6 +1218,8 @@ ehci_freex(struct usbd_bus *bus, struct return; } #endif + if ((task->state & USB_TASK_STATE_ONQ) != 0) + usb_rem_task(xfer->pipe->device, task); SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); } Index: sys/dev/usb/ohci.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ohci.c,v retrieving revision 1.111 diff -u -p -r1.111 ohci.c --- sys/dev/usb/ohci.c 19 Apr 2013 08:58:53 -0000 1.111 +++ sys/dev/usb/ohci.c 17 May 2013 08:37:13 -0000 @@ -974,6 +974,7 @@ void ohci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { struct ohci_softc *sc = (struct ohci_softc *)bus; + struct usb_task *task = &((struct ohci_xfer *)xfer)->abort_task; #ifdef DIAGNOSTIC if (xfer->busy_free != XFER_BUSY) { @@ -983,6 +984,8 @@ ohci_freex(struct usbd_bus *bus, struct } xfer->busy_free = XFER_FREE; #endif + if ((task->state & USB_TASK_STATE_ONQ) != 0) + usb_rem_task(xfer->pipe->device, task); SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); } Index: sys/dev/usb/uhci.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhci.c,v retrieving revision 1.96 diff -u -p -r1.96 uhci.c --- sys/dev/usb/uhci.c 19 Apr 2013 08:58:53 -0000 1.96 +++ sys/dev/usb/uhci.c 17 May 2013 08:37:14 -0000 @@ -653,6 +653,7 @@ void uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { struct uhci_softc *sc = (struct uhci_softc *)bus; + struct usb_task *task = &UXFER(xfer)->abort_task; #ifdef DIAGNOSTIC if (xfer->busy_free != XFER_BUSY) { @@ -666,6 +667,8 @@ uhci_freex(struct usbd_bus *bus, struct return; } #endif + if ((task->state & USB_TASK_STATE_ONQ) != 0) + usb_rem_task(xfer->pipe->device, task); SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); }