Patch "usb: gadget: pch_udc: reorder spin_[un]lock to avoid deadlock" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
usb: gadget: pch_udc: reorder spin_[un]lock to avoid deadlock
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-gadget-pch_udc-reorder-spin_lock-to-avoid-deadlock.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
1d23d16a88e6c8143b07339435ba061b131ebb8cMon Sep 17 00:00:00 2001
From: Iago Abal <[email protected]>
Date: Tue, 21 Jun 2016 12:01:11 +0200
Subject: usb: gadget: pch_udc: reorder spin_[un]lock to avoid deadlock
From: Iago Abal <[email protected]>
commit 1d23d16a88e6c8143b07339435ba061b131ebb8c upstream.
The above commit reordered spin_lock/unlock and now &dev->lock' is acquired (rather than released) before calling dev->driver->disconnect', dev->driver->setup', dev->driver->suspend', usb_gadget_giveback_request', and usb_gadget_udc_reset'.
But this *may* not be the right way to fix the problem pointed by d3cb25a12138.
Note that the other usb/gadget/udc drivers do release the lock before calling these functions. There are also inconsistencies within pch_udc.c, where dev->driver->disconnect' is called while holding &dev->lock' in lines 613 and 1184, but not in line 2739.
Finally, commit d3cb25a12138 may have introduced several potential deadlocks.
For instance, EBA (https://github.com/models-team/eba) reports:
Double lock in drivers/usb/gadget/udc/pch_udc.c
first at 2791: spin_lock(& dev->lock); [pch_udc_isr]
second at 2694: spin_lock(& dev->lock); [pch_udc_svc_cfg_interrupt]
after calling from 2793: pch_udc_dev_isr(dev, dev_intr);
after calling from 2724: pch_udc_svc_cfg_interrupt(dev);Similarly, other potential deadlocks are 2791 -> 2793 -> 2721 -> 2657; and 2791 -> 2793 -> 2711 -> 2573 -> 1499 -> 1480.
--- drivers/usb/gadget/udc/pch_udc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/usb/gadget/udc/pch_udc.c +8 -8
@@ -1477,11 +1477,11 @@ static void complete_req(struct pch_udc_ req->dma_mapped =0 ; } ep->halted =1 ; -spin_lock (&dev->lock); +spin_unlock (&dev->lock);if (!ep->in)pch_udc_ep_clear_rrdy (ep);usb_gadget_giveback_request (&ep->ep, &req->req); -spin_unlock (&dev->lock); +spin_lock (&dev->lock); ep->halted = halted; }
@@ -2573,9 +2573,9 @@ static void pch_udc_svc_ur_interrupt(strempty_req_queue (ep); }if (dev->driver) { -spin_lock (&dev->lock); -usb_gadget_udc_reset (&dev->gadget, dev->driver);spin_unlock (&dev->lock); +usb_gadget_udc_reset (&dev->gadget, dev->driver); +spin_lock (&dev->lock); } }
@@ -2654,9 +2654,9 @@ static void pch_udc_svc_intf_interrupt(s dev->ep[i].halted =0 ; } dev->stall =0 ; -spin_lock (&dev->lock); - dev->driver->setup (&dev->gadget, &dev->setup_data);spin_unlock (&dev->lock); + dev->driver->setup (&dev->gadget, &dev->setup_data); +spin_lock (&dev->lock); }/**
@@ -2691,9 +2691,9 @@ static void pch_udc_svc_cfg_interrupt(st dev->stall =0 ;/* call gadget zero with setup data received */ -spin_lock (&dev->lock); - dev->driver->setup (&dev->gadget, &dev->setup_data);spin_unlock (&dev->lock); + dev->driver->setup (&dev->gadget, &dev->setup_data); +spin_lock (&dev->lock); }/**
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/usb-gadget-pch_udc-reorder-spin_lock-to-avoid-deadlock.patch