Re: About resume time optimization for bus resume routine

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

 



On Wed, Oct 10, 2012 at 10:48:39AM -0400, Alan Stern wrote:
> On Wed, 10 Oct 2012, Peter Chen wrote:
> 
> > On Tue, Oct 09, 2012 at 11:03:47AM -0400, Alan Stern wrote:
> > > On Tue, 9 Oct 2012, Peter Chen wrote:
> > > 
> > > > Hi Alan,
> > > > 
> > > > When I try to optimize system resume time, I find bus resume routine
> > > > cost much time (> 20ms), even there is no device at any ports.
> > > > Let's take ehci bus resume as an example.
> > > > 
> > > > 1. At ehci_bus_resume
> > > > 
> > > > 	/* Some controller/firmware combinations need a delay during which
> > > > 	 * they set up the port statuses.  See Bugzilla #8190. */
> > > > 	spin_unlock_irq(&ehci->lock);
> > > > 	msleep(8);
> > > > 	spin_lock_irq(&ehci->lock);
> > > > Is it possible to add condition?
> > > 
> > > If you can come up with a good condition, sure.
> > According to Bugzilla #8190, the port status is not correct during
> > the suspend, can we use this as condition?, But we may can't find the tester.
> > 
> > See below comment:
> > 
> > Comment #18 From Alan Stern 2007-03-14 13:42:40
> > 
> > Created an attachment (id=10761) [details]
> > Diagnose EHCI port resume
> > 
> > This is very bizarre.  Here's the important part of the log, leaving out
> > everything except for port 3:
> > 
> > [    0.971514] ehci_hcd 0000:00:1d.7: port 3 status1 1005
> > [    0.991544] ehci_hcd 0000:00:1d.7: port 3 status2 1085
> > [    0.991546] ehci_hcd 0000:00:1d.7: resume done
> > 
> > The status1 value should be 1085 and the status2 value should be 10c5, meaning
> > that the port was suspended at first but then the resume bit was turned on. 
> > Instead the port was unsuspended at first and then somehow it got suspended! 
> > That's why the scanner wasn't working; it was still suspended.
> > 
> > Try using this new patch and see if it makes any difference.
> 
> Yes, I remember writing that.
> 
> You could test all the port status registers.  If any of them have the
> PORT_PE bit set and the PORT_SUSPEND bit clear then the delay is
> needed; otherwise it can be skipped.

I think the condition should like below, as we need to consider remote wakeup.
When remote wakeup occurs, it doesn't need this delay either.

if (portsc & PORT_PE) && ~(portsc & (PORT_SUSPEND | PORT_RESUME)))
	do_delay;
> 
> > > > 2. At hcd_bus_resume
> > > > 	if (status == 0) {
> > > > 		/* TRSMRCY = 10 msec */
> > > > 		msleep(10);
> > > > This 10ms delay is needed when the device is connected and CONFIG_USB_SUSPEND
> > > > is not defined, can we add condition like:
> > > 
> > > You should not depend on this.  In the future, the delay will be needed 
> > > even when CONFIG_USB_SUSPEND is defined.
> > > 
> > > > 	if (status == 0) {
> > > > 	#ifndef CONFIG_USB_SUSPEND
> > > > 		if (no_device_on_port)
> > > > 			/* TRSMRCY = 10 msec */
> > > > 			msleep(10);
> > > > 	#endif
> > > > For the no_device_on_port, it needs to add flag at struct usb_hcd.
> > 
> > Sorry, should be if (device_on_port)
> > > 
> > > In fact, with ehci-hcd this delay isn't needed at all.  
> > > ehci_bus_resume() does its own 20-ms delay if there are any unsuspended 
> > > enabled ports.
> > 
> > unsuspended enabled ports? According to my knowledge, only the port receives
> > remote-wakeup is unsuspended enabled port at that situation.
> 
> This has nothing to do with remote wakeup.

I mean the port status before roothub sends resume, only at remote wakeup
situation, that port status will be unsuspended enabled.
> 
> > According USB Spec 2.0, ch7.1.7.7:
> > The USB System Software must provide a 10 ms resume recovery time (TRSMRCY)
> > during which it will not attempt to access any device connected to the 
> > affected (just-activated) bus segment.
> > 
> > The TRSMRCY is needed after resume signal ends up, if the port is not
> > companion port, there is no 20ms delay at ehci_bus_resume.
> 
> You must be reading the wrong part of the code.  I'm talking about this
> part:
> 
> 	/* manually resume the ports we suspended during bus_suspend() */
> 	i = HCS_N_PORTS (ehci->hcs_params);
> 	while (i--) {
> 		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
> 		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
> 		if (test_bit(i, &ehci->bus_suspended) &&
> 				(temp & PORT_SUSPEND)) {
> 			temp |= PORT_RESUME;
> 			set_bit(i, &resume_needed);
> 		}
> 		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
> 	}
> 
> 	/* msleep for 20ms only if code is trying to resume port */
> 	if (resume_needed) {
> 		spin_unlock_irq(&ehci->lock);
> 		msleep(20);
> 		spin_lock_irq(&ehci->lock);
> 		if (ehci->shutdown)
> 			goto shutdown;
> 	}
> 
> That's the 20-ms delay, and it's not related to the companion 
> controller.
> 
> > If CONFIG_USB_SUSPEND is defined, and ehci->no_selective_suspend is not 
> > defined (only one Nvidia pci usb hcd defines it)
> > the usb_port_suspend/usb_port_resume will
> > do port suspend/resume(as well as msleep (10)) if there is a devivce 
> > on the port, the ehci_bus_suspend/ehci_bus_resume will not send suspend/resume.
> > so, the msleep (10) is not needed.
> 
> That's true now, but it won't be true in the future.  In the future, 
> usb_port_suspend() won't set the port's suspend feature when entering 
> system sleep, if the bus is USB-1 or USB-2.
> 
> > So, this 10ms delay at hcd_bus_resume is only needed meets below conditions:
> > - device on the port
> > - The resume is sent by bus resume routine
> > - There is no delay after resume signal ends up
> 
> It is needed under these conditions:
> 
> 	The HCD is not ehci-hcd.
If you have only delay above 20ms, and then clear PORT_RESUME, you
still need delay TRSMRCY, as TRSMRCY is the time after PORT_RESUME is
cleared.
> 
> 	There is a port on the root hub with suspend status clear
> 	and enabled status set (which implies there must be a device
> 	attached to the port, because disconnected ports can't be
> 	enabled).
> 
> Obviously if a port isn't enabled then it doesn't need any delay.
Is it ok to set one hcd flag, like hcd->unsuspended_device_on_port
to get condition at xxx_bus_suspend?
> 
> And if a port's suspend status is set then the port will remain 
> suspended after the root hub resumes, so again it doesn't need a delay.
> 
> In fact the second condition above works for every hub, not just root 
> hubs.
> 
> Alan Stern
> 
> 

-- 

Best Regards,
Peter Chen

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