UPSTREAM: scsi: core: Support failing requests while recovering

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>
Change-Id: I86867844b371d319fddccb87b8918ea2d850265a
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>
Bug: 258234315
(cherry picked from commit 310bcaef6d7ed1626bba95dd9b5c5acd189c0e35)
Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
Bart Van Assche
2022-10-18 13:29:51 -07:00
committed by Alistair Delva
parent ae2b84d37b
commit 25a21f1568
2 changed files with 7 additions and 4 deletions

View File

@@ -1328,9 +1328,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;
@@ -1662,6 +1659,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_IOERR;
goto out_dec_target_busy;
}
if (!scsi_host_queue_ready(q, shost, sdev, cmd))
goto out_dec_target_busy;

View File

@@ -59,8 +59,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