diff options
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.patch | 95 |
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 + |