Oliver Neukum <oliver@xxxxxxxxxx> writes: > Am Donnerstag, 26. April 2012, 15:41:15 schrieb Bjørn Mork: > >> Note that there is a significant delay (several seconds - up to a >> minute) before the actual lockup. Unloading the cdc-wdm driver during >> this stage does not prevent the bug, and does not cause any immediate >> crash either. So I believe this must be related to data living in the >> usb subsystem? Do we free a buffer referenced by an URB? >> >> > And could you provide an oops? >> >> A couple of the samples. Using qmi_wwan with cdc-wdm as a subdriver: >> >> [ 449.521234] qmi_wwan 5-4:1.8: Tx URB has been submitted index=8 > > from wdm_write() > > This means that set_bit(WDM_IN_USE, &desc->flags) has been executed > >> [ 449.523575] qmi_wwan 5-4:1.8: wdm_release: cleanup > > wdm_release() so wdm_flush() also has run. It will put itself on the waitqueue. > Very bad if disconnect() has freed the memory. > > > Please put in the printks Ran it with this bjorn@nemi:/usr/local/src/git/linux$ git diff diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 1fa7769..a0c1b3e 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -328,6 +328,8 @@ static ssize_t wdm_write struct wdm_device *desc = file->private_data; struct usb_ctrlrequest *req; + dev_dbg(&desc->intf->dev, "%s: desc->count=%d\n", __func__, desc->count); + if (count > desc->wMaxCommand) count = desc->wMaxCommand; @@ -526,6 +528,8 @@ static int wdm_flush(struct file *file, fl_owner_t id) { struct wdm_device *desc = file->private_data; + dev_dbg(&desc->intf->dev, "%s: desc->count=%d\n", __func__, desc->count); + wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); if (desc->werr < 0) dev_err(&desc->intf->dev, "Error in flush path: %d\n", @@ -879,6 +883,8 @@ static void wdm_disconnect(struct usb_interface *intf) desc = wdm_find_device(intf); mutex_lock(&wdm_mutex); + dev_dbg(&desc->intf->dev, "%s: desc->count=%d\n", __func__, desc->count); + /* the spinlock makes sure no new urbs are generated in the callbacks */ spin_lock_irqsave(&desc->iuspin, flags); set_bit(WDM_DISCONNECTING, &desc->flags); Didn't capture any Oops, BUG or whatever, but the system did lock up after a few seconds as expected. The last captured messages were: [35599.974533] usbcore: registered new interface driver cdc_wdm [35616.777152] qmi_wwan 2-4:1.8: cdc-wdm0: USB WDM device [35616.779043] qmi_wwan 2-4:1.8: wwan0: register 'qmi_wwan' at usb-0000:00:1d.7-4, Sierra Wireless wwan/QMI device, be:dc:79:7d:1c:72 [35616.785634] qmi_wwan 2-4:1.19: cdc-wdm1: USB WDM device [35616.787881] qmi_wwan 2-4:1.19: wwan1: register 'qmi_wwan' at usb-0000:00:1d.7-4, Sierra Wireless wwan/QMI device, be:dc:79:7d:1c:72 [35616.789005] qmi_wwan 2-4:1.20: not on our whitelist - ignored [35616.789308] usbcore: registered new interface driver qmi_wwan [35711.155922] qmi_wwan 2-4:1.8: wdm_write: desc->count=1 [35711.155934] qmi_wwan 2-4:1.8: Tx URB has been submitted index=8 [35711.156099] qmi_wwan 2-4:1.8: wdm_write: desc->count=1 [35711.158643] qmi_wwan 2-4:1.8: NOTIFY_RESPONSE_AVAILABLE received: index 8 len 0 [35711.158653] qmi_wwan 2-4:1.8: wdm_int_callback: usb_submit_urb 0 [35711.160175] qmi_wwan 2-4:1.8: wdm_flush: desc->count=1 [35711.160180] qmi_wwan 2-4:1.8: wdm_release: cleanup So nothing from the wdm_disconnect() call. But that is expected, isn't it? We don't disconnect from the device here. Bjørn -- 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