summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2014-02-19 11:22:34 +0800
committerNitin Garg <nitin.garg@freescale.com>2014-06-03 23:02:01 -0500
commitb2ecbbc90fa5397fdf3c57b80c8c59b80f46861d (patch)
tree41b8e756d92f78808789395d1ebd06d0b573b790
parent51b352a6eed537507e96c50d72ad4838f7443ea9 (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.c6
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;
}