On Fri, Mar 01, 2019 at 03:12:41PM -0600, Abel Abraham Camarillo Ojeda wrote:
> panic: assertwaitok: non-zero mutex count: 1
> Stopped at      0xffffffff813d9b8c:     jr      ra
> 0xffffffff813d9b90:      nop
>     TID    PID    UID     PRFLAGS     PFLAGS  CPU  COMMAND
> *328985  76286      0         0x3          0    0K mtree
> 0xffffffff813d9b88 (f040d88df76b5718,9001070000000208,208,0)  ra
> 0xffffffff8130

With help from Abel, I got the following stack trace from one of these
panics. It appears that dwctwo(4) incorrectly uses a blocking memory
allocation. The error gets uncovered by the upd(4) driver.

panic
__assertwaitok
malloc
dwc2_hcd_urb_alloc
dwc2_allocx
usbd_alloc_xfer
uhidev_get_report_async
upd_request_children
upd_update_report_cb
uhidev_get_report_async_cb
usb_transfer_complete
dwc2_softintr
softintr_dispatch
dosoftint
interrupt
k_intr
(interrupt)
pool_do_put
pool_put
namei
dofstatat
itsa
trap
u_general
(end of kernel stack)

The following patch makes the allocation non-blocking, so that
dwc2_allocx() behaves similarly to the other *_allocx() routines.
Abel has confirmed that this fixes the panic.

OK?

Index: dev/usb/dwc2/dwc2.c
===================================================================
RCS file: src/sys/dev/usb/dwc2/dwc2.c,v
retrieving revision 1.47
diff -u -p -r1.47 dwc2.c
--- dev/usb/dwc2/dwc2.c 11 Mar 2019 17:50:09 -0000      1.47
+++ dev/usb/dwc2/dwc2.c 13 Mar 2019 17:20:04 -0000
@@ -302,7 +302,11 @@ dwc2_allocx(struct usbd_bus *bus)
                memset(dxfer, 0, sizeof(*dxfer));
 
                dxfer->urb = dwc2_hcd_urb_alloc(sc->sc_hsotg,
-                   DWC2_MAXISOCPACKETS, GFP_KERNEL);
+                   DWC2_MAXISOCPACKETS, GFP_ATOMIC);
+               if (dxfer->urb == NULL) {
+                       pool_put(&sc->sc_xferpool, dxfer);
+                       return NULL;
+               }
 
 #ifdef DWC2_DEBUG
                dxfer->xfer.busy_free = XFER_ONQU;

Reply via email to