usbnet deadlock during urb unlink

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm encountering a recursive lock scenario in the usbnet urb unlink
path (triggered by 'ifconfig X down'). This is one of those cases
where I must be misunderstanding something because if my analysis is
correct everyone would be having this problem, not just me.

Summary is usbnet locks the rx queue so it can walk it invoking
usb_unlink_urb() on each urb. Each unlink call ends up in HCD-specific
urb_dequeue() which happily cancels the urb and invokes the
usb_hcd_giveback_urb() handler for it. The giveback handler ends up
back in usbnet rx_complete() which attempts to offload the work to a
bh. However, in the act of scheduling the bh it attempts to remove the
urb from rx queue which requires locking it and thus deadlocks since
it's already holding the lock in usb_unlink_urb().

usbnet_stop()
usbnet_terminate_urbs()
unlink_urbs() [locks rx queue]
usb_unlink_urb()
usb_hcd_unlink_urb()
<hcd-specific dequeue func>
usb_hcd_giveback_urb()
rx_complete()
defer_bh() [locks rx queue again]

My first instinct was that this was an HCD issue since I'm working
with an out-of-tree HCD (Samsung s3c otg-host). Perhaps the HCD is
supposed to giveback from interrupt context rather than directly on
the dequeue() path. However, looking at other HCD implementations it
appears they too giveback directly from their dequeue path.

What am I missing? Thanks in advance for any insight...

--Adam
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux