scsi: core: Support failing requests while recovering
authorBart Van Assche <bvanassche@acm.org>
Tue, 18 Oct 2022 20:29:51 +0000 (13:29 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 22 Oct 2022 03:25:59 +0000 (03:25 +0000)
The current behavior for SCSI commands submitted while error recovery is
ongoing is to retry command submission after error recovery has finished.
See also the scsi_host_in_recovery() check in scsi_host_queue_ready(). Add
support for failing SCSI commands while host recovery is in progress. This
functionality will be used to fix a deadlock in the UFS driver.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mike Christie <michael.christie@oracle.com>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20221018202958.1902564-4-bvanassche@acm.org
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_lib.c
include/scsi/scsi_cmnd.h

index fa96d3c..ec89086 100644 (file)
@@ -1341,9 +1341,6 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
                                   struct scsi_device *sdev,
                                   struct scsi_cmnd *cmd)
 {
-       if (scsi_host_in_recovery(shost))
-               return 0;
-
        if (atomic_read(&shost->host_blocked) > 0) {
                if (scsi_host_busy(shost) > 0)
                        goto starved;
@@ -1732,6 +1729,11 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
        ret = BLK_STS_RESOURCE;
        if (!scsi_target_queue_ready(shost, sdev))
                goto out_put_budget;
+       if (unlikely(scsi_host_in_recovery(shost))) {
+               if (cmd->flags & SCMD_FAIL_IF_RECOVERING)
+                       ret = BLK_STS_OFFLINE;
+               goto out_dec_target_busy;
+       }
        if (!scsi_host_queue_ready(q, shost, sdev, cmd))
                goto out_dec_target_busy;
 
index 7d3622d..c2cb5f6 100644 (file)
@@ -52,8 +52,9 @@ struct scsi_pointer {
 #define SCMD_TAGGED            (1 << 0)
 #define SCMD_INITIALIZED       (1 << 1)
 #define SCMD_LAST              (1 << 2)
+#define SCMD_FAIL_IF_RECOVERING        (1 << 4)
 /* flags preserved across unprep / reprep */
-#define SCMD_PRESERVED_FLAGS   (SCMD_INITIALIZED)
+#define SCMD_PRESERVED_FLAGS   (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING)
 
 /* for scmd->state */
 #define SCMD_STATE_COMPLETE    0