From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Alan Stern <stern@rowland.harvard.edu>
Subject: [013/102] USB: EHCI: go back to using the system clock for QH unlinks
Date: Wed, 03 Aug 2011 15:00:33 -0700 [thread overview]
Message-ID: <20110803221245.404143672@clark.kroah.org> (raw)
In-Reply-To: <20110803221345.GA10346@kroah.com>
3.0-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alan Stern <stern@rowland.harvard.edu>
commit 004c19682884d4f40000ce1ded53f4a1d0b18206 upstream.
This patch (as1477) fixes a problem affecting a few types of EHCI
controller. Contrary to what one might expect, these controllers
automatically stop their internal frame counter when no ports are
enabled. Since ehci-hcd currently relies on the frame counter for
determining when it should unlink QHs from the async schedule, those
controllers run into trouble: The frame counter stops and the QHs
never get unlinked.
Some systems have also experienced other problems traced back to
commit b963801164618e25fbdc0cd452ce49c3628b46c8 (USB: ehci-hcd unlink
speedups), which made the original switch from using the system clock
to using the frame counter. It never became clear what the reason was
for these problems, but evidently it is related to use of the frame
counter.
To fix all these problems, this patch more or less reverts that commit
and goes back to using the system clock. But this can't be done
cleanly because other changes have since been made to the scan_async()
subroutine. One of these changes involved the tricky logic that tries
to avoid rescanning QHs that have already been seen when the scanning
loop is restarted, which happens whenever an URB is given back.
Switching back to clock-based unlinks would make this logic even more
complicated.
Therefore the new code doesn't rescan the entire async list whenever a
giveback occurs. Instead it rescans only the current QH and continues
on from there. This requires the use of a separate pointer to keep
track of the next QH to scan, since the current QH may be unlinked
while the scanning is in progress. That new pointer must be global,
so that it can be adjusted forward whenever the _next_ QH gets
unlinked. (uhci-hcd uses this same trick.)
Simplification of the scanning loop removes a level of indentation,
which accounts for the size of the patch. The amount of code changed
is relatively small, and it isn't exactly a reversion of the
b963801164 commit.
This fixes Bugzilla #32432.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Matej Kenda <matejken@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/usb/host/ehci-hcd.c | 8 +---
drivers/usb/host/ehci-q.c | 86 +++++++++++++++++++++-----------------------
drivers/usb/host/ehci.h | 3 +
3 files changed, 47 insertions(+), 50 deletions(-)
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -94,7 +94,8 @@ static const char hcd_name [] = "ehci_hc
#define EHCI_IAA_MSECS 10 /* arbitrary */
#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
-#define EHCI_SHRINK_FRAMES 5 /* async qh unlink delay */
+#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1)
+ /* 200-ms async qh unlink delay */
/* Initial IRQ latency: faster than hw default */
static int log2_irq_thresh = 0; // 0 to 6
@@ -152,10 +153,7 @@ timer_action(struct ehci_hcd *ehci, enum
break;
/* case TIMER_ASYNC_SHRINK: */
default:
- /* add a jiffie since we synch against the
- * 8 KHz uframe counter.
- */
- t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
+ t = EHCI_SHRINK_JIFFIES;
break;
}
mod_timer(&ehci->watchdog, t + jiffies);
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1231,6 +1231,8 @@ static void start_unlink_async (struct e
prev->hw->hw_next = qh->hw->hw_next;
prev->qh_next = qh->qh_next;
+ if (ehci->qh_scan_next == qh)
+ ehci->qh_scan_next = qh->qh_next.qh;
wmb ();
/* If the controller isn't running, we don't have to wait for it */
@@ -1256,53 +1258,49 @@ static void scan_async (struct ehci_hcd
struct ehci_qh *qh;
enum ehci_timer_action action = TIMER_IO_WATCHDOG;
- ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index);
timer_action_done (ehci, TIMER_ASYNC_SHRINK);
-rescan:
stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);
- qh = ehci->async->qh_next.qh;
- if (likely (qh != NULL)) {
- do {
- /* clean any finished work for this qh */
- if (!list_empty(&qh->qtd_list) && (stopped ||
- qh->stamp != ehci->stamp)) {
- int temp;
-
- /* unlinks could happen here; completion
- * reporting drops the lock. rescan using
- * the latest schedule, but don't rescan
- * qhs we already finished (no looping)
- * unless the controller is stopped.
- */
- qh = qh_get (qh);
- qh->stamp = ehci->stamp;
- temp = qh_completions (ehci, qh);
- if (qh->needs_rescan)
- unlink_async(ehci, qh);
- qh_put (qh);
- if (temp != 0) {
- goto rescan;
- }
- }
-
- /* unlink idle entries, reducing DMA usage as well
- * as HCD schedule-scanning costs. delay for any qh
- * we just scanned, there's a not-unusual case that it
- * doesn't stay idle for long.
- * (plus, avoids some kind of re-activation race.)
- */
- if (list_empty(&qh->qtd_list)
- && qh->qh_state == QH_STATE_LINKED) {
- if (!ehci->reclaim && (stopped ||
- ((ehci->stamp - qh->stamp) & 0x1fff)
- >= EHCI_SHRINK_FRAMES * 8))
- start_unlink_async(ehci, qh);
- else
- action = TIMER_ASYNC_SHRINK;
- }
- qh = qh->qh_next.qh;
- } while (qh);
+ ehci->qh_scan_next = ehci->async->qh_next.qh;
+ while (ehci->qh_scan_next) {
+ qh = ehci->qh_scan_next;
+ ehci->qh_scan_next = qh->qh_next.qh;
+ rescan:
+ /* clean any finished work for this qh */
+ if (!list_empty(&qh->qtd_list)) {
+ int temp;
+
+ /*
+ * Unlinks could happen here; completion reporting
+ * drops the lock. That's why ehci->qh_scan_next
+ * always holds the next qh to scan; if the next qh
+ * gets unlinked then ehci->qh_scan_next is adjusted
+ * in start_unlink_async().
+ */
+ qh = qh_get(qh);
+ temp = qh_completions(ehci, qh);
+ if (qh->needs_rescan)
+ unlink_async(ehci, qh);
+ qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES;
+ qh_put(qh);
+ if (temp != 0)
+ goto rescan;
+ }
+
+ /* unlink idle entries, reducing DMA usage as well
+ * as HCD schedule-scanning costs. delay for any qh
+ * we just scanned, there's a not-unusual case that it
+ * doesn't stay idle for long.
+ * (plus, avoids some kind of re-activation race.)
+ */
+ if (list_empty(&qh->qtd_list)
+ && qh->qh_state == QH_STATE_LINKED) {
+ if (!ehci->reclaim && (stopped ||
+ time_after_eq(jiffies, qh->unlink_time)))
+ start_unlink_async(ehci, qh);
+ else
+ action = TIMER_ASYNC_SHRINK;
+ }
}
if (action == TIMER_ASYNC_SHRINK)
timer_action (ehci, TIMER_ASYNC_SHRINK);
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -75,6 +75,7 @@ struct ehci_hcd { /* one per controlle
struct ehci_qh *async;
struct ehci_qh *dummy; /* For AMD quirk use */
struct ehci_qh *reclaim;
+ struct ehci_qh *qh_scan_next;
unsigned scanning : 1;
/* periodic schedule support */
@@ -117,7 +118,6 @@ struct ehci_hcd { /* one per controlle
struct timer_list iaa_watchdog;
struct timer_list watchdog;
unsigned long actions;
- unsigned stamp;
unsigned periodic_stamp;
unsigned random_frame;
unsigned long next_statechange;
@@ -343,6 +343,7 @@ struct ehci_qh {
struct ehci_qh *reclaim; /* next to reclaim */
struct ehci_hcd *ehci;
+ unsigned long unlink_time;
/*
* Do NOT use atomic operations for QH refcounting. On some CPUs
next prev parent reply other threads:[~2011-08-03 23:25 UTC|newest]
Thread overview: 103+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-03 22:13 [000/102] 3.0.1-stable review Greg KH
2011-08-03 22:00 ` [001/102] USB: serial: add IDs for WinChipHead USB->RS232 adapter Greg KH
2011-08-03 22:00 ` [002/102] mmc: Added quirks for Ricoh 1180:e823 lower base clock frequency Greg KH
2011-08-03 22:00 ` [003/102] mmc: sdhci-esdhc-imx: SDHCI_CARD_PRESENT does not get cleared Greg KH
2011-08-03 22:00 ` [004/102] bridge: send proper message_age in config BPDU Greg KH
2011-08-03 22:00 ` [005/102] gro: Only reset frag0 when skb can be pulled Greg KH
2011-08-03 22:00 ` [006/102] Staging: usbip: vhci-hcd: Do not kill already dead RX/TX kthread Greg KH
2011-08-03 22:00 ` [007/102] staging: r8192e_pci: Handle duplicate PCI ID 0x10ec:0x8192 conflict with rtl8192se Greg KH
2011-08-03 22:00 ` [008/102] staging: comedi: fix infoleak to userspace Greg KH
2011-08-03 22:00 ` [009/102] Staging: hv: storvsc: Increase the timeout value in the storvsc driver Greg KH
2011-08-03 22:00 ` [010/102] Staging: hv: vmbus: Increase the timeout value in the vmbus driver Greg KH
2011-08-03 22:00 ` [011/102] Staging: hv: netvsc: Increase the timeout value in the netvsc driver Greg KH
2011-08-03 22:00 ` [012/102] USB: OHCI: fix another regression for NVIDIA controllers Greg KH
2011-08-03 22:00 ` Greg KH [this message]
2011-08-03 22:00 ` [014/102] usb: musb: restore INDEX register in resume path Greg KH
2011-08-03 22:00 ` [015/102] rtc: handle errors correctly in rtc_irq_set_state() Greg KH
2011-08-03 22:00 ` [016/102] rtc: fix hrtimer deadlock Greg KH
2011-08-03 22:00 ` [017/102] rtc: limit frequency Greg KH
2011-08-03 22:00 ` [018/102] drivers/rtc/rtc-tegra.c: properly initialize spinlock Greg KH
2011-08-03 22:00 ` [019/102] ARM: pxa/cm-x300: fix V3020 RTC functionality Greg KH
2011-08-03 22:00 ` [020/102] ASoC: davinci: add missing break statement Greg KH
2011-08-03 22:00 ` [021/102] ASoC: davinci: fix codec start and stop functions Greg KH
2011-08-03 22:00 ` [022/102] ASoC: Mark cache as dirty when suspending Greg KH
2011-08-03 22:00 ` [023/102] ath6kl: cache firmware Greg KH
2011-08-03 22:00 ` [024/102] ath6kl: fix crash when interface is closed but scan is ongoing Greg KH
2011-08-03 22:00 ` [025/102] ath9k_hw: Fix incorrect key_miss handling Greg KH
2011-08-03 22:00 ` [026/102] CIFS: Fix oops while mounting with prefixpath Greg KH
2011-08-03 22:00 ` [027/102] staging: brcm80211: fix for reported log spam problem Greg KH
2011-08-03 22:00 ` [028/102] jme: Fix unmap error (Causing system freeze) Greg KH
2011-08-03 22:00 ` [029/102] ethtool: Allow zero-length register dumps again Greg KH
2011-08-03 22:00 ` [030/102] firewire: cdev: return -ENOTTY for unimplemented ioctls, not -EINVAL Greg KH
2011-08-03 22:00 ` [031/102] firewire: cdev: prevent race between first get_info ioctl and bus reset event queuing Greg KH
2011-08-03 22:00 ` [032/102] IB/srp: Avoid duplicate devices from LUN scan Greg KH
2011-08-03 22:00 ` [033/102] [SCSI] libsas: remove expander from dev list on error Greg KH
2011-08-03 22:00 ` [034/102] rtlwifi: rtl8192cu: Fix duplicate if test Greg KH
2011-08-03 22:00 ` [035/102] mac80211: Restart STA timers only on associated state Greg KH
2011-08-03 22:00 ` [036/102] irq_work, ppc: Fix up arch hooks Greg KH
2011-08-03 22:00 ` [037/102] perf tools, x86: Fix 32-bit compile on 64-bit system Greg KH
2011-08-03 22:00 ` [038/102] perf tools: Fix endian conversion reading event attr from file header Greg KH
2011-08-03 22:00 ` [039/102] x86, intel, power: Initialize MSR_IA32_ENERGY_PERF_BIAS Greg KH
2011-08-03 22:01 ` [040/102] perf: Fix software event overflow Greg KH
2011-08-03 22:01 ` [041/102] [SCSI] Blacklist Traxdata CDR4120 and IOMEGA Zip drive to avoid lock ups Greg KH
2011-08-03 22:01 ` [042/102] [SCSI] sr: check_events() ignore GET_EVENT when TUR says otherwise Greg KH
2011-08-03 22:01 ` [043/102] [SCSI] ses: requesting a fault indication Greg KH
2011-08-03 22:01 ` [044/102] [SCSI] fix crash in scsi_dispatch_cmd() Greg KH
2011-08-03 22:01 ` [045/102] [SCSI] pmcraid: reject negative request size Greg KH
2011-08-03 22:01 ` [046/102] [SCSI] hpsa: do not attempt to read from a write-only register Greg KH
2011-08-03 22:01 ` [047/102] drm/radeon/kms: fix i2c map for rv250/280 Greg KH
2011-08-03 22:01 ` [048/102] drm/radeon/kms: fix DP training for DPEncoderService revision bigger than 1.1 Greg KH
2011-08-03 22:01 ` [049/102] drm/radeon/kms: add missing vddci setting on NI+ Greg KH
2011-08-03 22:01 ` [050/102] ALSA: virtuoso: fix silent analog output on Xonar Essence ST Deluxe Greg KH
2011-08-03 22:01 ` [051/102] ALSA: hda - Fix duplicated DAC assignments for Realtek Greg KH
2011-08-03 22:01 ` [052/102] pnfs: save layoutcommit lwb at layout header Greg KH
2011-08-03 22:01 ` [053/102] pnfs: save layoutcommit cred at layout header init Greg KH
2011-08-03 22:01 ` [054/102] pnfs: let layoutcommit handle a list of lseg Greg KH
2011-08-03 22:01 ` [055/102] pnfs: use lwb as layoutcommit length Greg KH
2011-08-03 22:01 ` [056/102] kexec, x86: Fix incorrect jump back address if not preserving context Greg KH
2011-08-03 22:01 ` [057/102] oprofile, x86: Fix nmi-unsafe callgraph support Greg KH
2011-08-03 22:01 ` [058/102] powerpc/kdump: Fix timeout in crash_kexec_wait_realmode Greg KH
2011-08-03 22:01 ` [059/102] irq_work, alpha: Fix up arch hooks Greg KH
2011-08-03 22:01 ` [060/102] tracing: Fix bug when reading system filters on module removal Greg KH
2011-08-03 22:01 ` [061/102] tracing: Have "enable" file use refcounts like the "filter" file Greg KH
2011-08-03 22:01 ` [062/102] XZ: Fix missing <linux/kernel.h> include Greg KH
2011-08-03 22:01 ` [063/102] PCI: ARI is a PCIe v2 feature Greg KH
2011-08-03 22:01 ` [064/102] cciss: do not attempt to read from a write-only register Greg KH
2011-08-03 22:01 ` [065/102] drivers/firmware/sigma.c needs MODULE_LICENSE Greg KH
2011-08-03 22:01 ` [066/102] geode: reflect mfgpt dependency on mfd Greg KH
2011-08-03 22:01 ` [067/102] mm/futex: fix futex writes on archs with SW tracking of dirty & young Greg KH
2011-08-03 22:01 ` [068/102] mm/backing-dev.c: reset bdi min_ratio in bdi_unregister() Greg KH
2011-08-03 22:01 ` [069/102] xtensa: prevent arbitrary read in ptrace Greg KH
2011-08-03 22:01 ` [070/102] ext4: fix i_blocks/quota accounting when extent insertion fails Greg KH
2011-08-03 22:01 ` [071/102] ext4: free allocated and pre-allocated blocks when check_eofblocks_fl fails Greg KH
2011-08-03 22:01 ` [072/102] ext3: Fix oops in ext3_try_to_allocate_with_rsv() Greg KH
2011-08-03 22:01 ` [073/102] ecryptfs: Make inode bdi consistent with superblock bdi Greg KH
2011-08-03 22:01 ` [074/102] eCryptfs: Unlock keys needed by ecryptfsd Greg KH
2011-08-03 22:01 ` [075/102] nfsd: dont break lease on CLAIM_DELEGATE_CUR Greg KH
2011-08-03 22:01 ` [076/102] nfsd4: remember to put RW access on stateid destruction Greg KH
2011-08-03 22:01 ` [077/102] nfsd4: fix file leak on open_downgrade Greg KH
2011-08-03 22:01 ` [078/102] svcrpc: fix list-corrupting race on nfsd shutdown Greg KH
2011-08-03 22:01 ` [079/102] NFSv4: Dont use the delegation->inode in nfs_mark_return_delegation() Greg KH
2011-08-03 22:01 ` [080/102] NFS: Fix spurious readdir cookie loop messages Greg KH
2011-08-03 22:01 ` [081/102] proc: fix a race in do_io_accounting() Greg KH
2011-08-03 22:01 ` [082/102] n_gsm: fix the wrong FCS handling Greg KH
2011-08-03 22:01 ` [083/102] EHCI: only power off port if over-current is active Greg KH
2011-08-03 22:01 ` [084/102] EHCI: fix direction handling for interrupt data toggles Greg KH
2011-08-03 22:01 ` [085/102] cfg80211: really ignore the regulatory request Greg KH
2011-08-03 22:01 ` [086/102] memcg: fix behavior of mem_cgroup_resize_limit() Greg KH
2011-08-03 22:01 ` [087/102] tty/serial: Fix XSCALE serial ports, e.g. ce4100 Greg KH
2011-08-03 22:01 ` [088/102] SERIAL: SC26xx: Fix link error Greg KH
2011-08-03 22:01 ` [089/102] powerpc/pseries/hvconsole: Fix dropped console output Greg KH
2011-08-03 22:01 ` [090/102] hvc_console: Improve tty/console put_chars handling Greg KH
2011-08-03 22:01 ` [091/102] ipc/sem.c: fix race with concurrent semtimedop() timeouts and IPC_RMID Greg KH
2011-08-03 22:01 ` [092/102] AppArmor: Fix reference to rcu protected pointer outside of rcu_read_lock Greg KH
2011-08-03 22:01 ` [093/102] AppArmor: Fix masking of capabilities in complain mode Greg KH
2011-08-03 22:01 ` [094/102] oom: task->mm == NULL doesnt mean the memory was freed Greg KH
2011-08-03 22:01 ` [095/102] rt2x00: Add device ID for RT539F device Greg KH
2011-08-03 22:01 ` [096/102] GFS2: Fix mount hang caused by certain access pattern to sysfs files Greg KH
2011-08-03 22:01 ` [097/102] watchdog: shwdt: fix usage of mod_timer Greg KH
2011-08-03 22:01 ` [098/102] ALSA: sound/core/pcm_compat.c: adjust array index Greg KH
2011-08-03 22:01 ` [099/102] dm io: flush cpu cache with vmapped io Greg KH
2011-08-03 22:02 ` [100/102] dm snapshot: flush disk cache when merging Greg KH
2011-08-03 22:02 ` [101/102] dm mpath: fix potential NULL pointer in feature arg processing Greg KH
2011-08-03 22:02 ` [102/102] dm: fix idr leak on module removal Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110803221245.404143672@clark.kroah.org \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=stable-review@kernel.org \
--cc=stable@kernel.org \
--cc=stern@rowland.harvard.edu \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®