On Wed, 18 Jun 2014, Mathias Nyman wrote: > On 06/17/2014 05:17 AM, Wang, Yu Y wrote: > > > > Hi All, > > > > I have one question about Linux xHCI driver. Need your help to introduce more backgrounds. > > About the S3 flow: > > 1, Freeze all user processes. > > 2, Freeze all kernel threads (including workqueue thread). > > 3, Trying to suspend all devices. > > 3.1, if pci device in RPM suspended, then try to resume it to D0. Call pm_runtime_resume API in prepare stage. > > 3.2, xhci_resume callback will call usb_hcd_resume_root_hub to queue two workqueue items to resume USB2&USB3 roothub devices. > > 3.3, call suspend callback of devices. > > 3.3.1, All suspend callback be called of hcd's children included roothub. > > 3.3.2, Finally, hcd_pci_suspend callback will be called. > > > > For above S3 enter flow. Due to workqueue thread were already > > frozen in step 2. So the two workqueue items can't be scheduled in > > step 3.2. But step 3.2 will set HCD_FLAG_WAKEUP_PENDING flag to hcd > > and shared_hcd which expecting clear in bus_resume which will not > > be executed in this scenario. It will cause step 3.3.2 return > > -EBUSY due to HCD_FLAG_WAKEUP_PENDING flag is set. Finally, S3 > > enter failed. > > > > As my debugging, I see sometimes, the HCD_FLAG_WAKEUP_PENDING flag > > will be clear in step 3.3.1 due to udev->do_remote_wakeup is not > > equal device_may_wakeup(&udev->dev) in choose_wakeup function. > > > > Is it by design behavior? Or it is just one lucky hit? It is a bug. And you are right; the only reason it doesn't show up very often is because of luck. > > Another question, step 3.2, why xhci_resume try to positive to > > resume its roothub devices? > > > > Hi > > This is a good question, I'm not that familiar with the internal details of pm framework or the usb core power management. > > The powermanagemnt workqueue (pm_wq) which is used by the PM framework is used here as well to resume the root hub > by calling hcd_bus_resume() which clears WAKEUP_PENDING flags. I have a hard time believing this workqueue can't be scheduled in the middle of > PM transitions activity. It can't, and for a very good reason: We don't want workqueue actions interfering with a system suspend by waking devices up after the PM core has powered them down. > I think that it should be possible to suspend a device already in runtime suspend without resuming it first. > This would at least make sure the runtime resume won't cause the system suspend to fail. It may or may not be possible, depending on the circumstances. Generally, if a device is in runtime suspend then it is enabled for wakeup (if it supports wakeup). But during system sleep, a device is supposed to be enabled for wakeup only if the user wants it to be. Root hubs in particular usually aren't wakeup-enabled during system sleep. You can imagine the trouble that would result if unplugging a USB mouse from a sleeping computer caused the computer to wake up. This means that for root hubs and various other devices, the wakeup settings have to be changed if the device is already in runtime suspend when a system sleep starts. And in general, you can't change a device's wakeup settings while it is powered down; you have to resume it first. That's why the PCI core does a runtime resume on every PCI device at the start of system sleep. It's overkill, but it allows wakeup settings to be adjusted properly. The problem here is that xhci_resume() assumes that it gets called _only_ when the root hubs are about to be resumed -- either because the whole system is waking up from sleep or because a USB device has sent a runtime wakeup request. But this isn't true during the initial stages of system suspend. When the PCI core does its runtime resume of the controller at this time, this does not have to cause the root hubs to resume. I'm not sure of the right way to solve this problem. Probably xhci_resume() should check the root-hub statuses to see if either root hub really needs to be resumed before calling usb_hcd_resume_root_hub(); I think that will work. Alan Stern -- 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