[PATCH] usb-storage: fix freezing of the scanning thread

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch (as1521) slightly improves the way usb-storage's
asynchronous scanning thread interacts with the freezer.  Rather than
making itself freezable before waiting for the device to settle, the
routine won't make itself freezable until after the settling delay.

This is just as correct as the existing code.  If the freezer starts
up before the delay is over then the scanning thread will be ignored
until the delay ends, at which point it will immediately be frozen.
On the other hand, if the freezer starts up after the delay is over
then it will wait for the scanning thread to finish, as it does now.

For the 3.3 kernel this change in behavior is not important.  However,
the backported version of this patch for the 3.2 kernel fixes a real
bug.  In 3.2, the scanning thread calls set_freezable_with_signal()
rather than set_freezable().  When the freezer runs, the resulting
signal delivery messes up the scanning thread's I/O delays, because
they are interruptible.

Thus the 3.2 version of this patch fixes the problem reported in
Bugzilla #42730.

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
CC: Seth Forshee <seth.forshee@xxxxxxxxxxxxx>
CC: <stable@xxxxxxxxxx>

---

 drivers/usb/storage/usb.c |   28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

Index: usb-3.3/drivers/usb/storage/usb.c
===================================================================
--- usb-3.3.orig/drivers/usb/storage/usb.c
+++ usb-3.3/drivers/usb/storage/usb.c
@@ -834,27 +834,23 @@ static int usb_stor_scan_thread(void * _
 
 	dev_dbg(dev, "device found\n");
 
-	set_freezable();
-
-	/*
-	 * Wait for the timeout to expire or for a disconnect
-	 *
-	 * We can't freeze in this thread or we risk causing khubd to
-	 * fail to freeze, but we can't be non-freezable either. Nor can
-	 * khubd freeze while waiting for scanning to complete as it may
-	 * hold the device lock, causing a hang when suspending devices.
-	 * So instead of using wait_event_freezable(), explicitly test
-	 * for (DONT_SCAN || freezing) in interruptible wait and proceed
-	 * if any of DONT_SCAN, freezing or timeout has happened.
-	 */
+	/* Wait for the timeout to expire or for a disconnect */
 	if (delay_use > 0) {
 		dev_dbg(dev, "waiting for device to settle "
 				"before scanning\n");
-		wait_event_interruptible_timeout(us->delay_wait,
-				test_bit(US_FLIDX_DONT_SCAN, &us->dflags) ||
-				freezing(current), delay_use * HZ);
+		wait_event_timeout(us->delay_wait,
+				test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
+				delay_use * HZ);
 	}
 
+	/*
+	 * We mustn't scan the device while it is suspended.  If a
+	 * system suspend has already started then this call will
+	 * freeze us immediately; if a suspend starts later then the
+	 * freezer will wait until we are finished scanning.
+	 */
+	set_freezable();
+
 	/* If the device is still connected, perform the scanning */
 	if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) {
 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux