RE: FW: ehci->watchdog timer panic

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

 



 
Alan,

Thanks you for your quick response. Is it possible that the watchdog be
scheduled as a result of some activity on the device side. I'm not sure
if there is a race condition when the host is trying to suspend the bus
while the device is sending something.

Thanks,
Fei

-----Original Message-----
From: Alan Stern [mailto:stern@xxxxxxxxxxxxxxxxxxx] 
Sent: Monday, June 29, 2009 10:48 AM
To: Yang Fei-AFY095
Cc: linux-usb@xxxxxxxxxxxxxxx; Gadiyar, Anand; Pandita, Vikram;
Ghongdemath, Girish
Subject: Re: FW: ehci->watchdog timer panic

On Mon, 29 Jun 2009, Yang Fei-AFY095 wrote:

> Hello All,
> 
> I am looking for some advice on the correct method for utlising the
> ehci_bus_suspend() function on an OMAP3 device. On the OMAP3 device 
> the usbhost controller is in a separate internal power-domain. So when

> the usbhost is inactive or suspend is called, we can disable clocks 
> and power-down the usbhost to save power.
> 
> Recently we found that after calling ehci_bus_suspend() and disabling 
> the usbhost clocks we would see the ehci watchdog timer event fire. 
> This was causing a kernel panic because the usbhost controllers clocks

> were disabled and inside the watchdog timer function the clocks were 
> not being re-enabled, so when the ehci registers were accessed this 
> resulted in a CPU data-abort.
> 
> From reviewing the ehci_bus_suspend() function, I do see that after 
> deleting any pending watchdog timer events, there is a called made to
> ehci_work() (see below code snippet). From looking at the ehci_work() 
> function it does appear to be possible that another watchdog timer 
> event could be scheduled, but I have been unable to confirm this.

ehci_work can enable the watchdog timer.

> Unfortunately, this failure is not easily reproduced. 
> 
>  --- snip ---
> 
> static int ehci_bus_suspend (struct usb_hcd *hcd) {
>         struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
>         int                     port;
>         int                     mask;
> 
>         ehci_dbg(ehci, "suspend root hub\n");
> 
>         if (time_before (jiffies, ehci->next_statechange))
>                 msleep(5);
>         del_timer_sync(&ehci->watchdog);
>         del_timer_sync(&ehci->iaa_watchdog);
> 
>         port = HCS_N_PORTS (ehci->hcs_params);
>         spin_lock_irq (&ehci->lock);
> 
>         /* stop schedules, clean any completed work */
>         if (HC_IS_RUNNING(hcd->state)) {
>                 ehci_quiesce (ehci);
>                 hcd->state = HC_STATE_QUIESCING;
>         }
>         ehci->command = ehci_readl(ehci, &ehci->regs->command);
>         ehci_work(ehci);
> 
>  --- snip ---
> 
> Hence, I wanted to ask the following questions:
> 
> 1). Theoretically is it possible that a call to ehci_work() during the

> suspend could cause another watchdog timer event to be scheduled?

In theory, maybe.  It's hard to examine all the possible code paths to
tell for sure.  But whatever timer event is pending, it can't be
important.

> 2). If there is a watchdog event pending after calling 
> ehci_bus_suspend(), should we:
> a). Make the function, ehci_bus_suspend, return an error code -EBUSY 
> to indicate there is still work pending? See below.

No.

> b). Make the function calling the ehci_bus_suspend, returns an error 
> to indicate that we could not disable the clocks and suspend failed?

No.  Simply add another call to del_timer_sync at the very end of
ehci_bus_suspend (after the spin_unlock_irq).  Include a comment
explaining that ehci_work may have re-enabled the timer, so it has to be
turned off again.

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