USB: ehci - fix timer regression
This patch fixes a regression in the EHCI driver's TIMER_IO_WATCHDOG behavior. The patch "USB: EHCI: add separate IAA watchdog timer" changed how that timer is handled, so that short timeouts on the remaining timer (unfortunately, overloaded) would never be used. This takes a more direct approach, reorganizing the code slightly to be explicit about only the I/O watchdog role now being overridable. It also replaces a now-obsolete comment describing older timer behavior. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Leonid <leonidv11@gmail.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
4b828abed2
Коммит
056761e55c
|
@ -177,6 +177,15 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
||||||
static inline void
|
static inline void
|
||||||
timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
||||||
{
|
{
|
||||||
|
/* Don't override timeouts which shrink or (later) disable
|
||||||
|
* the async ring; just the I/O watchdog. Note that if a
|
||||||
|
* SHRINK were pending, OFF would never be requested.
|
||||||
|
*/
|
||||||
|
if (timer_pending(&ehci->watchdog)
|
||||||
|
&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
|
||||||
|
& ehci->actions))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!test_and_set_bit (action, &ehci->actions)) {
|
if (!test_and_set_bit (action, &ehci->actions)) {
|
||||||
unsigned long t;
|
unsigned long t;
|
||||||
|
|
||||||
|
@ -192,15 +201,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
|
||||||
t = EHCI_SHRINK_JIFFIES;
|
t = EHCI_SHRINK_JIFFIES;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t += jiffies;
|
mod_timer(&ehci->watchdog, t + jiffies);
|
||||||
// all timings except IAA watchdog can be overridden.
|
|
||||||
// async queue SHRINK often precedes IAA. while it's ready
|
|
||||||
// to go OFF neither can matter, and afterwards the IO
|
|
||||||
// watchdog stops unless there's still periodic traffic.
|
|
||||||
if (time_before_eq(t, ehci->watchdog.expires)
|
|
||||||
&& timer_pending (&ehci->watchdog))
|
|
||||||
return;
|
|
||||||
mod_timer (&ehci->watchdog, t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче