diff options
author | Peter Chen <peter.chen@freescale.com> | 2014-02-19 11:22:34 +0800 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-06-03 23:02:01 -0500 |
commit | b2ecbbc90fa5397fdf3c57b80c8c59b80f46861d (patch) | |
tree | 41b8e756d92f78808789395d1ebd06d0b573b790 | |
parent | 51b352a6eed537507e96c50d72ad4838f7443ea9 (diff) |
driver: scsi: Stop accepting SCSI requests before removing a device
Based on Bart Van Assche's below patch
Avoid that the code for requeueing SCSI requests triggers a
crash by making sure that that code isn't scheduled anymore
after a device has been removed.
Also, source code inspection of __scsi_remove_device() revealed
a race condition in this function: no new SCSI requests must be
accepted for a SCSI device after device removal started.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dd454c4f99aa..2dab9a41ed4e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -153,13 +153,15 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy) /* * Requeue this command. It will go before all other commands - * that are already in the queue. + * that are already in the queue. Schedule requeue work under + * lock such that the kblockd_schedule_work() call happens + * before blk_cleanup_queue() finishes. */ spin_lock_irqsave(q->queue_lock, flags); blk_requeue_request(q, cmd->request); - spin_unlock_irqrestore(q->queue_lock, flags); kblockd_schedule_work(q, &device->requeue_work); + spin_unlock_irqrestore(q->queue_lock, flags); return 0; } |