diff options
author | Jianchao Wang <jianchao.w.wang@oracle.com> | 2018-03-03 09:54:09 +0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-03-06 21:16:33 -0500 |
commit | 2f793a27d58f0fb302f8e162b46fe4b366bbdedd (patch) | |
tree | 04cef37a0265f155ab760e6606a19df9e36bdcd8 /drivers/scsi/scsi_lib.c | |
parent | 61b142afb2e28d4f06e158399409d181ad91949c (diff) | |
download | linux-2f793a27d58f0fb302f8e162b46fe4b366bbdedd.tar.gz linux-2f793a27d58f0fb302f8e162b46fe4b366bbdedd.tar.bz2 linux-2f793a27d58f0fb302f8e162b46fe4b366bbdedd.zip |
scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
In scsi core, __scsi_queue_insert should just put request back on the
queue and retry using the same command as before. However, for blk-mq,
scsi_mq_requeue_cmd is employed here which will unprepare the
request. To align with the semantics of __scsi_queue_insert, use
blk_mq_requeue_request with kick_requeue_list == true and put the
reference of scsi_device.
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jianchao Wang <jianchao.w.wang@oracle.com>
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index aea5a1ae318b..10430d500792 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -191,7 +191,19 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) */ cmd->result = 0; if (q->mq_ops) { - scsi_mq_requeue_cmd(cmd); + /* + * Before a SCSI command is dispatched, + * get_device(&sdev->sdev_gendev) is called and the host, + * target and device busy counters are increased. Since + * requeuing a request causes these actions to be repeated and + * since scsi_device_unbusy() has already been called, + * put_device(&device->sdev_gendev) must still be called. Call + * put_device() after blk_mq_requeue_request() to avoid that + * removal of the SCSI device can start before requeueing has + * happened. + */ + blk_mq_requeue_request(cmd->request, true); + put_device(&device->sdev_gendev); return; } spin_lock_irqsave(q->queue_lock, flags); |