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.

[Yu:] Thanks for help confirm.

> 
> > > 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.

[Yu:] I understand your point. From the big picture, to my understanding, there have
three scenarios.

The first one is USB device trigger remote wakeup. 

The second one is user space trying to resume xHC which will queue URBs.

The third one is PCI driver try to resume pci device during S3 entering if the device
under suspended state.

Your patch is focus on the first case. Avoid xHCI re-enter RPM suspended in the gap
between HCD resumed and activate the IRQ, right?

But your patch will cause this BUG for the third case. And the second case should be fine.
So my understanding is to find one way to distinguish the first one and second one.
We need to confirm if RH need to resume before trigger resume in xhci_resume.
During xhci_resume function, after set USBCMD.R/S bit, then the controller can get IRQ.
So we can check USBSTS.EINT or USBSTS.PCD bit to determine if need to resume the
root hubs to handle these events.

Please correct me if my understanding is not correct.

Thanks
Yu
--
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