Re: [PATCH v4] xhci - correct comp_mode_recovery_timer on return from hibernate

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

 



On Wed, 6 Mar 2013, Don Zickus wrote:

> On Tue, Mar 05, 2013 at 03:14:10PM -0800, Sarah Sharp wrote:
> > >   */
> > >  static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
> > >  {
> > > +	if (timer_pending(&xhci->comp_mode_recovery_timer)) {
> > > +		xhci_dbg(xhci, "Compliance Mode Recovery Timer already active.\n");
> > > +		return;
> > > +	}
> > > +
> > >  	xhci->port_status_u0 = 0;
> > >  	init_timer(&xhci->comp_mode_recovery_timer);
> > 
> > Isn't this racy?  There's no locking here, so what if the timer fired
> > just before the call to timer_pending happened?  (The documentation on
> > the timer interface doesn't describe whether timer_pending returns true
> > if we're in the middle of a timer callback.)
> 
> Ah, yes.  I think I misled Tony here.  I thought the timer_pending() check
> just checked to see if the timer was on the linked list, not realizing the
> timer is removed from that list when executed.  Instead I thought the
> expires was set to -1 (or something large that it never expired) but it
> stayed on the list.
> 
> We might have to dumb it down and just use a global init variable that is
> set/cleared by the compliance functions with the assumption they are
> called serially (as not to race).
> 
> Though this all seems very hackish and ugly.  There has to be a better way
> to do this.. :-(

The init_timer call should occur only once, during the probe routine.  
Later calls should use mod_timer.  It's okay to call mod_timer while 
the timer routine is running; in fact, many timer routines call 
mod_timer themselves.

> > Also, looking at the compliance timer callback brings up further
> > questions:
> > 
> > static void compliance_mode_recovery(unsigned long arg)
> > {
> > ...
> >         for (i = 0; i < xhci->num_usb3_ports; i++) {
> >                 temp = xhci_readl(xhci, xhci->usb3_ports[i]);
> >                 if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
> >                         /*
> >                          * Compliance Mode Detected. Letting USB Core
> >                          * handle the Warm Reset
> >                          */
> > 
> > What happens when the xHCI host controller goes into D3cold due to
> > runtime PM?  The port status registers will read as all f's, so we will
> > miss any transitions to the compliance mode that happened before or
> > during the transition to D3cold.
> > 
> > This code probably needs to wake up the host controller and keep it from
> > suspending until all the ports can be read.
> 
> Fun...  I take it there is no document that describes the various paths PM
> can take during each of these phases?

Certainly there is: Documentation/power/devices.txt.  Of course, this 
describes the various paths in the PM core, not in the PM 
implementations of specific drivers such as xhci-hcd.

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