aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2011-08-25 12:57:34 -0400
committerLeann Ogasawara <leann.ogasawara@canonical.com>2011-08-30 17:34:20 -0400
commit2e9bc59b0cb91f9f47924f4e44dcb91f25b37192 (patch)
treedae2ca82fd9a01b0d7dd0b0b633b054138069464 /drivers/usb
parent59f39ae033092eac5bd90f208adcc7bf894dce74 (diff)
UBUNTU: SAUCE: (drop after 3.1) usb_storage: Don't freeze in usb-stor-scan
Should be merged for 3.2.0 BugLink: http://bugs.launchpad.net/bugs/810020 Scanning cannot be run during suspend or hibernation, but if usb-stor-scan freezes another thread waiting on scanning to complete may fail to freeze. However, if usb-stor-scan is left freezable without ever actually freezing then the freezer will wait on it to exit, and threads waiting for scanning to finish will no longer be blocked. One problem with this approach is that usb-stor-scan has a delay to wait for devices to settle (which is currently the only point where it can freeze). To work around this we can request that the freezer send a fake signal when freezing, then use interruptible sleep to wake the thread early when freezing happens. To make this happen, the following changes are made to usb-stor-scan: * Use set_freezable_with_signal() instead of set_freezable() to request a fake signal when freezing * Use wait_event_interruptible_timeout() instead of wait_event_freezable_timeout() to avoid freezing Signed-off-by: Seth Forshee <seth.forshee@canonical.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/storage/usb.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 0ca095820f3..c325e69415a 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -831,12 +831,22 @@ static int usb_stor_scan_thread(void * __us)
831 831
832 dev_dbg(dev, "device found\n"); 832 dev_dbg(dev, "device found\n");
833 833
834 set_freezable(); 834 set_freezable_with_signal();
835 /* Wait for the timeout to expire or for a disconnect */ 835 /*
836 * Wait for the timeout to expire or for a disconnect
837 *
838 * We can't freeze in this thread or we risk causing khubd to
839 * fail to freeze, but we can't be non-freezable either. Nor can
840 * khubd freeze while waiting for scanning to complete as it may
841 * hold the device lock, causing a hang when suspending devices.
842 * So we request a fake signal when freezing and use
843 * interruptible sleep to kick us out of our wait early when
844 * freezing happens.
845 */
836 if (delay_use > 0) { 846 if (delay_use > 0) {
837 dev_dbg(dev, "waiting for device to settle " 847 dev_dbg(dev, "waiting for device to settle "
838 "before scanning\n"); 848 "before scanning\n");
839 wait_event_freezable_timeout(us->delay_wait, 849 wait_event_interruptible_timeout(us->delay_wait,
840 test_bit(US_FLIDX_DONT_SCAN, &us->dflags), 850 test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
841 delay_use * HZ); 851 delay_use * HZ);
842 } 852 }