Message ID | 1526901487-22438-1-git-send-email-yoshihiro.shimoda.uh@renesas.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Greg, Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> writes: > When printer_write() calls usb_ep_queue(), a udc driver (e.g. > renesas_usbhs driver) may call usb_gadget_giveback_request() in > the udc .queue ops immediately. Then, printer_write() calls > list_add(&req->list, &dev->tx_reqs_active) wrongly. After that, > if we do unbind the printer driver, WARN_ON() happens in > printer_func_unbind() because the list entry is not removed. > > So, this patch moves list_add(&req->list, &dev->tx_reqs_active) > calling before usb_ep_queue(). > > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> > Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> I'm not sure if you're still taking bug fixes for current -rc cycle, but if you are, please take this directly. If you're done with v4.17, please apply this on top of my pull request which I sent an hour or so ago. Thanks
diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index d359efe..9c7ed25 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -631,19 +631,19 @@ static void tx_complete(struct usb_ep *ep, struct usb_request *req) return -EAGAIN; } + list_add(&req->list, &dev->tx_reqs_active); + /* here, we unlock, and only unlock, to avoid deadlock. */ spin_unlock(&dev->lock); value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); spin_lock(&dev->lock); if (value) { + list_del(&req->list); list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); return -EAGAIN; } - - list_add(&req->list, &dev->tx_reqs_active); - } spin_unlock_irqrestore(&dev->lock, flags);