aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0df15cb738d2..0dbf25512778 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1642,8 +1642,18 @@ static blk_status_t scsi_mq_prep_fn(struct request *req)
1642 1642
1643static void scsi_mq_done(struct scsi_cmnd *cmd) 1643static void scsi_mq_done(struct scsi_cmnd *cmd)
1644{ 1644{
1645 if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state)))
1646 return;
1645 trace_scsi_dispatch_cmd_done(cmd); 1647 trace_scsi_dispatch_cmd_done(cmd);
1646 blk_mq_complete_request(cmd->request); 1648
1649 /*
1650 * If the block layer didn't complete the request due to a timeout
1651 * injection, scsi must clear its internal completed state so that the
1652 * timeout handler will see it needs to escalate its own error
1653 * recovery.
1654 */
1655 if (unlikely(!blk_mq_complete_request(cmd->request)))
1656 clear_bit(SCMD_STATE_COMPLETE, &cmd->state);
1647} 1657}
1648 1658
1649static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) 1659static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx)
@@ -1702,6 +1712,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
1702 if (!scsi_host_queue_ready(q, shost, sdev)) 1712 if (!scsi_host_queue_ready(q, shost, sdev))
1703 goto out_dec_target_busy; 1713 goto out_dec_target_busy;
1704 1714
1715 clear_bit(SCMD_STATE_COMPLETE, &cmd->state);
1705 if (!(req->rq_flags & RQF_DONTPREP)) { 1716 if (!(req->rq_flags & RQF_DONTPREP)) {
1706 ret = scsi_mq_prep_fn(req); 1717 ret = scsi_mq_prep_fn(req);
1707 if (ret != BLK_STS_OK) 1718 if (ret != BLK_STS_OK)