diff options
author | James Bottomley <James.Bottomley@suse.de> | 2011-01-27 16:12:37 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-12 10:17:13 -0600 |
commit | 563585ec4bf1319f193c2f51682985bcae400cb4 (patch) | |
tree | de6d2b98f972fc9a414c5d39638c5c0bc3c4a09a /drivers/scsi/qla2xxx | |
parent | 3c6c0d6ca386fe7a8e44e887a51f333c2499c829 (diff) | |
download | linux-stable-563585ec4bf1319f193c2f51682985bcae400cb4.tar.gz linux-stable-563585ec4bf1319f193c2f51682985bcae400cb4.tar.bz2 linux-stable-563585ec4bf1319f193c2f51682985bcae400cb4.zip |
[SCSI] qla2xxx: Fix race that could hang kthread_stop()
There is a small race window in qla2x00_do_dpc() between
checking for kthread_should_stop() and going to sleep after
setting TASK_INTERRUPTIBLE. If qla2x00_free_device() is called
in this window, kthread_stop will wait forever because there
will be no one to wake up the process.
Fix by making sure we only set TASK_INTERRUPTIBLE before checking
kthread_stop().
Reported-by: Bandan Das <bandan.das@stratus.com>
Acked-by: Madhuranath Iyengar <Madhu.Iyengar@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c194c23ca1fb..15ce69eaaf4d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data) set_user_nice(current, -20); + set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { DEBUG3(printk("qla2x00: DPC handler sleeping\n")); - set_current_state(TASK_INTERRUPTIBLE); schedule(); __set_current_state(TASK_RUNNING); @@ -3454,7 +3454,9 @@ qla2x00_do_dpc(void *data) qla2x00_do_dpc_all_vps(base_vha); ha->dpc_active = 0; + set_current_state(TASK_INTERRUPTIBLE); } /* End of while(1) */ + __set_current_state(TASK_RUNNING); DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); |