usb: ehci: Reduce overhead of the scan_periodic loop

scan_periodic is called with irq disabled. Merged Alan Stern's patch
to reduce the overhead of scan_periodic:

http://article.gmane.org/gmane.linux.usb.general/37441
Here is a patch which ought to reduce the overhead of the loop. It
avoids doing the expensive call to qh_completions() more than once
for each qh.

Change-Id: I218c75a1ce21edd3d58c7e8abd3e7f75880b6ad0
Signed-off-by: Benoit Goby <benoit@android.com>
This commit is contained in:
Benoit Goby
2010-12-08 18:28:39 -08:00
parent 85f7f645fb
commit bad2e94f96
3 changed files with 12 additions and 4 deletions

View File

@@ -838,6 +838,7 @@ qh_make (
is_input, 0,
hb_mult(maxp) * max_packet(maxp)));
qh->start = NO_FRAME;
qh->stamp = ehci->periodic_stamp;
if (urb->dev->speed == USB_SPEED_HIGH) {
qh->c_usecs = 0;

View File

@@ -2261,6 +2261,7 @@ scan_periodic (struct ehci_hcd *ehci)
}
clock &= mod - 1;
clock_frame = clock >> 3;
++ehci->periodic_stamp;
for (;;) {
union ehci_shadow q, *q_p;
@@ -2289,10 +2290,14 @@ restart:
temp.qh = qh_get (q.qh);
type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
q = q.qh->qh_next;
modified = qh_completions (ehci, temp.qh);
if (unlikely(list_empty(&temp.qh->qtd_list) ||
temp.qh->needs_rescan))
intr_deschedule (ehci, temp.qh);
if (temp.qh->stamp != ehci->periodic_stamp) {
modified = qh_completions(ehci, temp.qh);
if (!modified)
temp.qh->stamp = ehci->periodic_stamp;
if (unlikely(list_empty(&temp.qh->qtd_list) ||
temp.qh->needs_rescan))
intr_deschedule(ehci, temp.qh);
}
qh_put (temp.qh);
break;
case Q_TYPE_FSTN:
@@ -2427,6 +2432,7 @@ restart:
free_cached_lists(ehci);
ehci->clock_frame = clock_frame;
}
++ehci->periodic_stamp;
} else {
now_uframe++;
now_uframe &= mod - 1;

View File

@@ -117,6 +117,7 @@ struct ehci_hcd { /* one per controller */
struct timer_list watchdog;
unsigned long actions;
unsigned stamp;
unsigned periodic_stamp;
unsigned random_frame;
unsigned long next_statechange;
ktime_t last_periodic_enable;