RE: [BUG] usb_dev_resume returns -113 due to work items queued by usb on pm_wq is not executed before suspending.

From: Du, ChangbinX
Date: Mon Aug 18 2014 - 07:54:36 EST


> On Fri, 15 Aug 2014, Du, ChangbinX wrote:
> > If my analysis is correct, could you share your ideas for this issue?
>
> Hasn't this already been fixed? See commit d6236f6d1d88 (xhci: Fix runtime
> suspended xhci from blocking system suspend).
>
> Alan Stern

Hi, Stern,
These are two different issues. Commit d6236f6d1d88 fixes issue that xhci runtime
pm logical blocks system suspend. But the issue we are encountering is usb device
resuming fail and lead to device reset.

This issue can be reproduced by below steps:
1) Plug a usb device to usb3 host, and make sure this device can enter runtime
suspend state.
2) Wait HCD entering runtime suspend state.( xhci_suspend() will be called)
3) Make system starts system suspending. On this step, PM core freeze threads and
resume hcd & the usb device to runtime active state(xhci_resume() will be called,
and roothub resuming work item is queued). Then calls the suspend callbacks of devices'.
4) We force system suspending process aborted (by modifying code) just after the usb
Device suspend callback is invoked.
5) Then PM core will call resume callback of the usb device to recovery. On this step
usb_dev_resume() invokes and it return -113 error. Because the can_submit flag of
root hub is 0. Root hub resuming work item is still pending.

The sequence is:
xhci_suspend() ---> host runtime suspend
PM: Syncing filesystems ... done.
PM: Preparing system for mem sleep
Freezing user space processes
xhci_resume() ---> resume to runtime active, work item queued ,
but the roothub is not resumed(can_submit=0).
PM: Entering mem sleep
... ---> invoke device suspend callbacks
1-1:1.0: device suspending
...
PM: Some devices failed to suspend ---> suspending process aborted and starts recovery
.... ---> call resuming callbacks for suspended devices
1-1:1.0: usb_dev_resume() -> usb_resume ->
usb_resume_both()->generic_resume()->
usb_port_resume()->hub_port_status()->
usb_control_msg()->usb_submit_urb()->
usb_hcd_link_urb_to_ep()

int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)
{
...
if (unlikely(!urb->dev->can_submit)) {
rc = -EHOSTUNREACH; // -113
goto done;
}
...
}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/