From bad2e94f96154d3a2ac5cc8a5acdc615bc37635a Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Wed, 8 Dec 2010 18:28:39 -0800 Subject: [PATCH] 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 --- drivers/usb/host/ehci-q.c | 1 + drivers/usb/host/ehci-sched.c | 14 ++++++++++---- drivers/usb/host/ehci.h | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 760118370e73..95bd514c0d06 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -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; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a92526d6e5ae..fa442c5ec16b 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -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; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 9dd486abd621..530540a4bdd4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -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; -- 2.34.1