On Thu, 5 Oct 2017, David Tulloh wrote:
> Thanks Alan,
>
> I was facing a different problem but your suggestion put me on the right path.
>
> Sorry it took me so long to update the thread, it has taken me a while
> to get a basic understanding of the debugging tools and processes
> built into the kernel.
>
> My issue was the rare beast, a consistently repeatable lock contention.
> The wonderful LOCK_DEP output summarises it better than I could.
>
> Unfortunately I don't understand the locking requirements nearly well
> enough to craft a patch.
>
>
> Now I have solved this issue (turn off SMP) I'm looking forward to see
> if the isochronous problem bites me too.
>
>
> David
>
>
> [ 88.361471] ============================================
> [ 88.362014] WARNING: possible recursive locking detected
> [ 88.362580] 4.14.0-rc2+ #9 Not tainted
> [ 88.363010] --------------------------------------------
> [ 88.363561] v4l_id/526 is trying to acquire lock:
> [ 88.364062] (&(&cdev->lock)->rlock){....}, at:
> [<ffffffffa0547e03>] composite_disconnect+0x43/0x100 [libcomposite]
> [ 88.365051]
> [ 88.365051] but task is already holding lock:
> [ 88.365826] (&(&cdev->lock)->rlock){....}, at:
> [<ffffffffa0547b09>] usb_function_deactivate+0x29/0x80 [libcomposite]
> [ 88.366858]
> [ 88.366858] other info that might help us debug this:
> [ 88.368301] Possible unsafe locking scenario:
> [ 88.368301]
> [ 88.369304] CPU0
> [ 88.369701] ----
> [ 88.370101] lock(&(&cdev->lock)->rlock);
> [ 88.370623] lock(&(&cdev->lock)->rlock);
> [ 88.371145]
> [ 88.371145] *** DEADLOCK ***
> [ 88.371145]
> [ 88.372211] May be due to missing lock nesting notation
> [ 88.372211]
> [ 88.373191] 2 locks held by v4l_id/526:
> [ 88.373715] #0: (&(&cdev->lock)->rlock){....}, at:
> [<ffffffffa0547b09>] usb_function_deactivate+0x29/0x80 [libcomposite]
> [ 88.374814] #1: (&(&dum_hcd->dum->lock)->rlock){....}, at:
> [<ffffffffa05bd48d>] dummy_pullup+0x7d/0xf0 [dummy_hcd]
> [ 88.376289]
> [ 88.376289] stack backtrace:
> [ 88.377726] CPU: 0 PID: 526 Comm: v4l_id Not tainted 4.14.0-rc2+ #9
> [ 88.378557] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
> BIOS 1.10.2-1 04/01/2014
> [ 88.379504] Call Trace:
> [ 88.380019] dump_stack+0x86/0xc7
> [ 88.380605] __lock_acquire+0x841/0x1120
> [ 88.381252] lock_acquire+0xd5/0x1c0
> [ 88.381865] ? composite_disconnect+0x43/0x100 [libcomposite]
> [ 88.382668] _raw_spin_lock_irqsave+0x40/0x54
> [ 88.383357] ? composite_disconnect+0x43/0x100 [libcomposite]
> [ 88.384290] composite_disconnect+0x43/0x100 [libcomposite]
> [ 88.385490] set_link_state+0x2d4/0x3c0 [dummy_hcd]
> [ 88.386436] dummy_pullup+0xa7/0xf0 [dummy_hcd]
> [ 88.387195] usb_gadget_disconnect+0xd8/0x160 [udc_core]
> [ 88.387990] usb_gadget_deactivate+0xd3/0x160 [udc_core]
> [ 88.388793] usb_function_deactivate+0x64/0x80 [libcomposite]
> [ 88.389628] uvc_function_disconnect+0x1e/0x40 [usb_f_uvc]
> [ 88.390445] uvc_v4l2_release+0x33/0x90 [usb_f_uvc]
This looks like a bug in dummy-hcd. It calls the gadget driver's
disconnect callback when the D+ pullup is turned off rather than when
Vbus power is turned off.
Felipe, can you confirm my understanding of how a UDC driver is
supposed to behave?
David, please try the patch below. It should fix this problem. And I
have no idea why I didn't encounter exactly the same recursive locking
error in my own testing...
Alan Stern
Index: usb-4.x/drivers/usb/gadget/udc/dummy_hcd.c
===================================================================
--- usb-4.x.orig/drivers/usb/gadget/udc/dummy_hcd.c
+++ usb-4.x/drivers/usb/gadget/udc/dummy_hcd.c
@@ -433,6 +433,7 @@ static void set_link_state_by_speed(stru
static void set_link_state(struct dummy_hcd *dum_hcd)
{
struct dummy *dum = dum_hcd->dum;
+ unsigned int power_bit;
dum_hcd->active = 0;
if (dum->pullup)
@@ -443,15 +444,17 @@ static void set_link_state(struct dummy_
return;
set_link_state_by_speed(dum_hcd);
+ power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
+ USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
dum_hcd->active)
dum_hcd->resuming = 0;
/* Currently !connected or in reset */
- if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
+ if ((dum_hcd->port_status & power_bit) == 0 ||
(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
- unsigned disconnect = USB_PORT_STAT_CONNECTION &
+ unsigned disconnect = power_bit &
dum_hcd->old_status & (~dum_hcd->port_status);
unsigned reset = USB_PORT_STAT_RESET &
(~dum_hcd->old_status) & dum_hcd->port_status;
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html