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