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