Skip to content

Commit 5424930

Browse files
brianatpurestoragemartinkpetersen
authored andcommitted
scsi: core: Allow the ALUA transitioning state enough time
The error path for the SCSI check condition of not ready, target in ALUA state transition, will result in the failure of that path after the retries are exhausted. In most cases that is well ahead of the transition timeout established in the SCSI ALUA device handler. Instead, reprep the command and re-add it to the queue after a 1 second delay. This will allow the handler to take care of the timeout and only fail the path if the target has exceeded the transition expiry timeout (default 60 seconds). If the expiry timeout is exceeded, the handler will change the path state from transitioning to standby leading to a path failure eliminating the potential of this re-prep to continue endlessly. In most cases the target will exit the transitioning state well before the expiry timeout but after the retries are exhausted as mentioned. Additionally remove the scsi_io_completion_reprep() function which provides little value. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Martin Wilck <[email protected]> Acked-by: Krishna Kant <[email protected]> Acked-by: Seamus Connor <[email protected]> Signed-off-by: Brian Bunker <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 53661de commit 5424930

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

drivers/scsi/scsi_lib.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ scsi_set_blocked(struct scsi_cmnd *cmd, int reason)
111111
}
112112
}
113113

114-
static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
114+
static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd, unsigned long msecs)
115115
{
116116
struct request *rq = scsi_cmd_to_rq(cmd);
117117

@@ -121,7 +121,12 @@ static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
121121
} else {
122122
WARN_ON_ONCE(true);
123123
}
124-
blk_mq_requeue_request(rq, true);
124+
125+
if (msecs) {
126+
blk_mq_requeue_request(rq, false);
127+
blk_mq_delay_kick_requeue_list(rq->q, msecs);
128+
} else
129+
blk_mq_requeue_request(rq, true);
125130
}
126131

127132
/**
@@ -651,14 +656,6 @@ static unsigned int scsi_rq_err_bytes(const struct request *rq)
651656
return bytes;
652657
}
653658

654-
/* Helper for scsi_io_completion() when "reprep" action required. */
655-
static void scsi_io_completion_reprep(struct scsi_cmnd *cmd,
656-
struct request_queue *q)
657-
{
658-
/* A new command will be prepared and issued. */
659-
scsi_mq_requeue_cmd(cmd);
660-
}
661-
662659
static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd)
663660
{
664661
struct request *req = scsi_cmd_to_rq(cmd);
@@ -676,14 +673,21 @@ static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd)
676673
return false;
677674
}
678675

676+
/*
677+
* When ALUA transition state is returned, reprep the cmd to
678+
* use the ALUA handler's transition timeout. Delay the reprep
679+
* 1 sec to avoid aggressive retries of the target in that
680+
* state.
681+
*/
682+
#define ALUA_TRANSITION_REPREP_DELAY 1000
683+
679684
/* Helper for scsi_io_completion() when special action required. */
680685
static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
681686
{
682-
struct request_queue *q = cmd->device->request_queue;
683687
struct request *req = scsi_cmd_to_rq(cmd);
684688
int level = 0;
685-
enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY,
686-
ACTION_DELAYED_RETRY} action;
689+
enum {ACTION_FAIL, ACTION_REPREP, ACTION_DELAYED_REPREP,
690+
ACTION_RETRY, ACTION_DELAYED_RETRY} action;
687691
struct scsi_sense_hdr sshdr;
688692
bool sense_valid;
689693
bool sense_current = true; /* false implies "deferred sense" */
@@ -772,8 +776,8 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
772776
action = ACTION_DELAYED_RETRY;
773777
break;
774778
case 0x0a: /* ALUA state transition */
775-
blk_stat = BLK_STS_TRANSPORT;
776-
fallthrough;
779+
action = ACTION_DELAYED_REPREP;
780+
break;
777781
default:
778782
action = ACTION_FAIL;
779783
break;
@@ -832,7 +836,10 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
832836
return;
833837
fallthrough;
834838
case ACTION_REPREP:
835-
scsi_io_completion_reprep(cmd, q);
839+
scsi_mq_requeue_cmd(cmd, 0);
840+
break;
841+
case ACTION_DELAYED_REPREP:
842+
scsi_mq_requeue_cmd(cmd, ALUA_TRANSITION_REPREP_DELAY);
836843
break;
837844
case ACTION_RETRY:
838845
/* Retry the same command immediately */
@@ -926,7 +933,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
926933
* command block will be released and the queue function will be goosed. If we
927934
* are not done then we have to figure out what to do next:
928935
*
929-
* a) We can call scsi_io_completion_reprep(). The request will be
936+
* a) We can call scsi_mq_requeue_cmd(). The request will be
930937
* unprepared and put back on the queue. Then a new command will
931938
* be created for it. This should be used if we made forward
932939
* progress, or if we want to switch from READ(10) to READ(6) for
@@ -942,7 +949,6 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
942949
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
943950
{
944951
int result = cmd->result;
945-
struct request_queue *q = cmd->device->request_queue;
946952
struct request *req = scsi_cmd_to_rq(cmd);
947953
blk_status_t blk_stat = BLK_STS_OK;
948954

@@ -979,7 +985,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
979985
* request just queue the command up again.
980986
*/
981987
if (likely(result == 0))
982-
scsi_io_completion_reprep(cmd, q);
988+
scsi_mq_requeue_cmd(cmd, 0);
983989
else
984990
scsi_io_completion_action(cmd, result);
985991
}

0 commit comments

Comments
 (0)