On Wed, 20 Feb 2013, Don Zickus wrote: > On Wed, Feb 20, 2013 at 10:54:40AM -0500, Alan Stern wrote: > > On Wed, 20 Feb 2013, Tony Camuso wrote: > > > > > On 02/20/2013 10:15 AM, Alan Stern wrote: > > > > On Tue, 19 Feb 2013, Sarah Sharp wrote: > > > > > > > >> The one thing I wanted to check was my understanding of the hibernate > > > >> flow path. As you mentioned, I thought that xhci_suspend would be > > > >> called in the hibernate path, but it's not. > > > > > > > > Are you sure about that? AFAICT it should be called -- although it > > > > gets called during the poweroff phase of hibernation, not the freeze > > > > phase. > > > > > > > > core/hcd-pci.c: usb_hcd_pci_pm_ops.poweroff = hcd_pci_suspend > > > > core/hcd-pci.c: hcd_pci_suspend calls suspend_common > > > > core/hcd-pci.c: suspend_common calls hcd->driver->pci_suspend > > > > host/xhci-pci.c: xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend > > > > host/xhci-pci.c: xhci_pci_suspend calls xhci_suspend > > > > > > > We instrumented the code, and when invoking pm-hibernate, we did > > > not flow through xhci_suspend(), where the timer is deleted. > > > > If you instrumented the code then you ought to know how the actual > > behavior differs from what I outlined above. Where is the difference? > > Hi Alan, > > I worked with Tony on this issue. The instrumentation we did was to add > printks in the xhci_suspend, xhci_resume and > compliance_mode_recovery_timer_init. > > What we noticed was that the xhci_suspend was not called during hibernate. I bet it really was called, but you didn't realize it because of the way you monitored the output from the printks. You looked at the log buffer or the kernel log file after resuming, right? You didn't have a serial console attached to another machine, to capture the output as it occurred. This makes a difference, because output that occurs after the memory image is stored on disk will not be present in the image and hence will not be visible after you resume from hibernation. Of course, in your case this doesn't matter. In the memory image, the timer is active. Hence it is still active when the system resumes, even though xhci_suspend _was_ called. > As a result the timer was not deleted. During the resume, xhci_init > called compliance_mode_recovery_timer_init which caused the initial panic > (adding an existing timer). > > We added code to compliance_mode_recovery_timer_init to bail if the timer > was already enabled. This lead us to the second problem at the bottom of > xhci_resume where compliance_mode_recovery_timer_init was called again. > > We did not attempt to understand the mechanics of how suspend/hibernate > and resume worked. We just assumed based on the hibernate flag to > xhci_resume there were two code paths. If you want to handle hibernation correctly, you have to understand how it works. It is all described in excruciating detail in Documentation/power/devices.txt. > If the expectation is that xhci_suspend should be called during hibernate, > I can work with Tony to figure out why this is not happening. Solving > that problem would partially solve our problem. We would still need the > !hibernate flag at the bottom of xhci_resume to surround the timer check > to deal with xhci_init calling the same init function. Resuming from hibernation is not like resuming from system suspend, for two important reasons: After hibernation, the system has gone through a complete reboot. The BIOS has probably made changes, and devices generally need to be completely reinitialized. The state a driver sees following hibernation is the state that existed during the "freeze" phase, which is different from what you get during system suspend (and also different from what you get during later phases of hibernation). 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