Commit b4f93012 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] ehci, async idle timout

One more patch:  this turns off async schedule processing
if there are no control or bulk transactions for a while
(currently HZ/3).  Consequence:  no PCI accesses unless
there's work to do.  (And a FIXME comment is gone!)
parent dcd37e86
......@@ -111,6 +111,7 @@
#define EHCI_TUNE_MULT_TT 1
#define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */
#define EHCI_ASYNC_JIFFIES (HZ/3) /* async idle timeout */
/* Initial IRQ latency: lower than default */
static int log2_irq_thresh = 0; // 0 to 6
......@@ -247,9 +248,14 @@ static void ehci_watchdog (unsigned long param)
struct ehci_hcd *ehci = (struct ehci_hcd *) param;
unsigned long flags;
/* guard against lost IAA, which wedges everything */
spin_lock_irqsave (&ehci->lock, flags);
/* guard against lost IAA, which wedges everything */
ehci_irq (&ehci->hcd);
/* unlink the last qh after it's idled a while */
if (ehci->async_idle) {
start_unlink_async (ehci, ehci->async);
ehci->async_idle = 0;
}
spin_unlock_irqrestore (&ehci->lock, flags);
}
......
......@@ -736,6 +736,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
qh->qh_state = QH_STATE_LINKED;
/* qtd completions reported later by interrupt */
ehci->async_idle = 0;
}
/*-------------------------------------------------------------------------*/
......@@ -1004,16 +1006,18 @@ scan_async (struct ehci_hcd *ehci, unsigned long flags)
}
/* unlink idle entries, reducing HC PCI usage as
* well as HCD schedule-scanning costs
* well as HCD schedule-scanning costs. removing
* the last qh is deferred, since it's costly.
*/
if (list_empty (&qh->qtd_list) && !ehci->reclaim) {
if (qh->qh_next.qh != qh) {
// dbg ("irq/empty");
start_unlink_async (ehci, qh);
} else {
// FIXME: arrange to stop
// after it's been idle a while.
// stop/restart isn't free...
} else if (!timer_pending (&ehci->watchdog)) {
/* can't use IAA for last entry */
ehci->async_idle = 1;
mod_timer (&ehci->watchdog,
jiffies + EHCI_ASYNC_JIFFIES);
}
}
qh = qh->qh_next.qh;
......
......@@ -39,7 +39,8 @@ struct ehci_hcd { /* one per controller */
/* async schedule support */
struct ehci_qh *async;
struct ehci_qh *reclaim;
int reclaim_ready;
int reclaim_ready : 1,
async_idle : 1;
/* periodic schedule support */
#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment