aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/usb.h
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2012-02-21 13:16:32 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-21 19:29:15 -0500
commitbb94a406682770a35305daaa241ccdb7cab399de (patch)
treea6801c8edec8809e34c34ec889db4682f074c923 /drivers/usb/storage/usb.h
parent9a9a71b77c3fd511e5dda6236deb8a02d156b864 (diff)
usb-storage: fix freezing of the scanning thread
This patch (as1521b) fixes the interaction between usb-storage's scanning thread and the freezer. The current implementation has a race: If the device is unplugged shortly after being plugged in and just as a system sleep begins, the scanning thread may get frozen before the khubd task. Khubd won't be able to freeze until the disconnect processing is complete, and the disconnect processing can't proceed until the scanning thread finishes, so the sleep transition will fail. The implementation in the 3.2 kernel suffers from an additional problem. There the scanning thread calls set_freezable_with_signal(), and the signals sent by the freezer will mess up the thread's I/O delays, which are all interruptible. The solution to both problems is the same: Replace the kernel thread used for scanning with a delayed-work routine on the system freezable work queue. Freezable work queues have the nice property that you can cancel a work item even while the work queue is frozen, and no signals are needed. The 3.2 version of this patch solves the problem in Bugzilla #42730. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Seth Forshee <seth.forshee@canonical.com> CC: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/storage/usb.h')
-rw-r--r--drivers/usb/storage/usb.h7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 7b0f2113632e..75f70f04f37b 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -47,6 +47,7 @@
47#include <linux/blkdev.h> 47#include <linux/blkdev.h>
48#include <linux/completion.h> 48#include <linux/completion.h>
49#include <linux/mutex.h> 49#include <linux/mutex.h>
50#include <linux/workqueue.h>
50#include <scsi/scsi_host.h> 51#include <scsi/scsi_host.h>
51 52
52struct us_data; 53struct us_data;
@@ -72,7 +73,7 @@ struct us_unusual_dev {
72#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ 73#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */
73#define US_FLIDX_RESETTING 4 /* device reset in progress */ 74#define US_FLIDX_RESETTING 4 /* device reset in progress */
74#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ 75#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
75#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ 76#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */
76#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ 77#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */
77#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ 78#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */
78 79
@@ -147,8 +148,8 @@ struct us_data {
147 /* mutual exclusion and synchronization structures */ 148 /* mutual exclusion and synchronization structures */
148 struct completion cmnd_ready; /* to sleep thread on */ 149 struct completion cmnd_ready; /* to sleep thread on */
149 struct completion notify; /* thread begin/end */ 150 struct completion notify; /* thread begin/end */
150 wait_queue_head_t delay_wait; /* wait during scan, reset */ 151 wait_queue_head_t delay_wait; /* wait during reset */
151 struct completion scanning_done; /* wait for scan thread */ 152 struct delayed_work scan_dwork; /* for async scanning */
152 153
153 /* subdriver information */ 154 /* subdriver information */
154 void *extra; /* Any extra data */ 155 void *extra; /* Any extra data */