summaryrefslogtreecommitdiffstats
path: root/freed-ora/current/f14/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch
diff options
context:
space:
mode:
Diffstat (limited to 'freed-ora/current/f14/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch')
-rw-r--r--freed-ora/current/f14/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch95
1 files changed, 95 insertions, 0 deletions
diff --git a/freed-ora/current/f14/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch b/freed-ora/current/f14/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch
new file mode 100644
index 000000000..499c31a02
--- /dev/null
+++ b/freed-ora/current/f14/0001-EHCI-don-t-rescan-interrupt-QHs-needlessly.patch
@@ -0,0 +1,95 @@
+From 1729d20333739e6cc23023e405fe8668f08117a2 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 17 May 2011 10:40:51 -0400
+Subject: [PATCH 1/2] EHCI: don't rescan interrupt QHs needlessly
+
+This patch (as1466) speeds up processing of ehci-hcd's periodic list.
+The existing code will pointlessly rescan an interrupt endpoint queue
+each time it encounters the queue's QH in the periodic list, which can
+happen quite a few times if the endpoint's period is low. On some
+embedded systems, this useless overhead can waste so much time that
+the driver falls hopelessly behind and loses events.
+
+The patch introduces a "periodic_stamp" variable, which gets
+incremented each time scan_periodic() runs and each time the scan
+advances to a new frame. If the corresponding stamp in an interrupt
+QH is equal to the current periodic_stamp, we assume the QH has
+already been scanned and skip over it. Otherwise we scan the QH as
+usual, and if none of its URBs have completed then we store the
+current periodic_stamp in the QH's stamp, preventing it from being
+scanned again.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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 ed8db6a..0079610 100644
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -826,6 +826,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 a530856..9e54e85 100644
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -2351,6 +2351,7 @@ scan_periodic (struct ehci_hcd *ehci)
+ }
+ clock %= mod;
+ clock_frame = clock >> 3;
++ ++ehci->periodic_stamp;
+
+ for (;;) {
+ union ehci_shadow q, *q_p;
+@@ -2379,10 +2380,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:
+@@ -2515,6 +2520,7 @@ restart:
+ if (ehci->clock_frame != clock_frame) {
+ free_cached_lists(ehci);
+ ehci->clock_frame = clock_frame;
++ ++ehci->periodic_stamp;
+ }
+ } else {
+ now_uframe++;
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+index c702e4b..c2c2f9d 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;
+--
+1.7.6
+
OpenPOWER on IntegriCloud