Re: [Intel-linux-usb] RE: One question about Linux xHCI driver

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

 



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




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

  Powered by Linux