Skip to content

Commit 3f90ac7

Browse files
Merge patch series "scsi: Allow scsi_execute users to request retries"
Mike Christie <michael.christie@oracle.com> says: The following patches were made over Linus's tree which contains a fix for sd which was not in Martin's branches. The patches allow scsi_execute_cmd users to have scsi-ml retry the cmd for it instead of the caller having to parse the error and loop itself. Link: https://lore.kernel.org/r/20240123002220.129141-1-michael.christie@oracle.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2 parents 8179041 + 25a1f7a commit 3f90ac7

File tree

13 files changed

+894
-263
lines changed

13 files changed

+894
-263
lines changed

drivers/scsi/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ config SCSI_PROC_FS
6767

6868
If unsure say Y.
6969

70+
config SCSI_LIB_KUNIT_TEST
71+
tristate "KUnit tests for SCSI Mid Layer's scsi_lib" if !KUNIT_ALL_TESTS
72+
depends on KUNIT
73+
default KUNIT_ALL_TESTS
74+
help
75+
Run SCSI Mid Layer's KUnit tests for scsi_lib.
76+
77+
If unsure say N.
78+
7079
comment "SCSI support type (disk, tape, CD-ROM)"
7180
depends on SCSI
7281

drivers/scsi/ch.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ typedef struct {
113113
struct scsi_device **dt; /* ptrs to data transfer elements */
114114
u_int firsts[CH_TYPES];
115115
u_int counts[CH_TYPES];
116-
u_int unit_attention;
117116
u_int voltags;
118117
struct mutex lock;
119118
} scsi_changer;
@@ -186,17 +185,29 @@ static int
186185
ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
187186
void *buffer, unsigned int buflength, enum req_op op)
188187
{
189-
int errno, retries = 0, timeout, result;
188+
int errno = 0, timeout, result;
190189
struct scsi_sense_hdr sshdr;
190+
struct scsi_failure failure_defs[] = {
191+
{
192+
.sense = UNIT_ATTENTION,
193+
.asc = SCMD_FAILURE_ASC_ANY,
194+
.ascq = SCMD_FAILURE_ASCQ_ANY,
195+
.allowed = 3,
196+
.result = SAM_STAT_CHECK_CONDITION,
197+
},
198+
{}
199+
};
200+
struct scsi_failures failures = {
201+
.failure_definitions = failure_defs,
202+
};
191203
const struct scsi_exec_args exec_args = {
192204
.sshdr = &sshdr,
205+
.failures = &failures,
193206
};
194207

195208
timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
196209
? timeout_init : timeout_move;
197210

198-
retry:
199-
errno = 0;
200211
result = scsi_execute_cmd(ch->device, cmd, op, buffer, buflength,
201212
timeout * HZ, MAX_RETRIES, &exec_args);
202213
if (result < 0)
@@ -205,14 +216,6 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
205216
if (debug)
206217
scsi_print_sense_hdr(ch->device, ch->name, &sshdr);
207218
errno = ch_find_errno(&sshdr);
208-
209-
switch(sshdr.sense_key) {
210-
case UNIT_ATTENTION:
211-
ch->unit_attention = 1;
212-
if (retries++ < 3)
213-
goto retry;
214-
break;
215-
}
216219
}
217220
return errno;
218221
}

drivers/scsi/device_handler/scsi_dh_hp_sw.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ static int tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h,
4646
int ret = SCSI_DH_IO;
4747

4848
switch (sshdr->sense_key) {
49-
case UNIT_ATTENTION:
50-
ret = SCSI_DH_IMM_RETRY;
51-
break;
5249
case NOT_READY:
5350
if (sshdr->asc == 0x04 && sshdr->ascq == 2) {
5451
/*
@@ -85,11 +82,24 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
8582
int ret, res;
8683
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
8784
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
85+
struct scsi_failure failure_defs[] = {
86+
{
87+
.sense = UNIT_ATTENTION,
88+
.asc = SCMD_FAILURE_ASC_ANY,
89+
.ascq = SCMD_FAILURE_ASCQ_ANY,
90+
.allowed = SCMD_FAILURE_NO_LIMIT,
91+
.result = SAM_STAT_CHECK_CONDITION,
92+
},
93+
{}
94+
};
95+
struct scsi_failures failures = {
96+
.failure_definitions = failure_defs,
97+
};
8898
const struct scsi_exec_args exec_args = {
8999
.sshdr = &sshdr,
100+
.failures = &failures,
90101
};
91102

92-
retry:
93103
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
94104
HP_SW_RETRIES, &exec_args);
95105
if (res > 0 && scsi_sense_valid(&sshdr)) {
@@ -104,9 +114,6 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
104114
ret = SCSI_DH_IO;
105115
}
106116

107-
if (ret == SCSI_DH_IMM_RETRY)
108-
goto retry;
109-
110117
return ret;
111118
}
112119

@@ -122,14 +129,31 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
122129
struct scsi_sense_hdr sshdr;
123130
struct scsi_device *sdev = h->sdev;
124131
int res, rc;
125-
int retry_cnt = HP_SW_RETRIES;
126132
blk_opf_t opf = REQ_OP_DRV_IN | REQ_FAILFAST_DEV |
127133
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
134+
struct scsi_failure failure_defs[] = {
135+
{
136+
/*
137+
* LUN not ready - manual intervention required
138+
*
139+
* Switch-over in progress, retry.
140+
*/
141+
.sense = NOT_READY,
142+
.asc = 0x04,
143+
.ascq = 0x03,
144+
.allowed = HP_SW_RETRIES,
145+
.result = SAM_STAT_CHECK_CONDITION,
146+
},
147+
{}
148+
};
149+
struct scsi_failures failures = {
150+
.failure_definitions = failure_defs,
151+
};
128152
const struct scsi_exec_args exec_args = {
129153
.sshdr = &sshdr,
154+
.failures = &failures,
130155
};
131156

132-
retry:
133157
res = scsi_execute_cmd(sdev, cmd, opf, NULL, 0, HP_SW_TIMEOUT,
134158
HP_SW_RETRIES, &exec_args);
135159
if (!res) {
@@ -144,13 +168,6 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
144168
switch (sshdr.sense_key) {
145169
case NOT_READY:
146170
if (sshdr.asc == 0x04 && sshdr.ascq == 3) {
147-
/*
148-
* LUN not ready - manual intervention required
149-
*
150-
* Switch-over in progress, retry.
151-
*/
152-
if (--retry_cnt)
153-
goto retry;
154171
rc = SCSI_DH_RETRY;
155172
break;
156173
}

drivers/scsi/device_handler/scsi_dh_rdac.c

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -485,43 +485,17 @@ static int set_mode_select(struct scsi_device *sdev, struct rdac_dh_data *h)
485485
static int mode_select_handle_sense(struct scsi_device *sdev,
486486
struct scsi_sense_hdr *sense_hdr)
487487
{
488-
int err = SCSI_DH_IO;
489488
struct rdac_dh_data *h = sdev->handler_data;
490489

491490
if (!scsi_sense_valid(sense_hdr))
492-
goto done;
493-
494-
switch (sense_hdr->sense_key) {
495-
case NO_SENSE:
496-
case ABORTED_COMMAND:
497-
case UNIT_ATTENTION:
498-
err = SCSI_DH_RETRY;
499-
break;
500-
case NOT_READY:
501-
if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x01)
502-
/* LUN Not Ready and is in the Process of Becoming
503-
* Ready
504-
*/
505-
err = SCSI_DH_RETRY;
506-
break;
507-
case ILLEGAL_REQUEST:
508-
if (sense_hdr->asc == 0x91 && sense_hdr->ascq == 0x36)
509-
/*
510-
* Command Lock contention
511-
*/
512-
err = SCSI_DH_IMM_RETRY;
513-
break;
514-
default:
515-
break;
516-
}
491+
return SCSI_DH_IO;
517492

518493
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
519494
"MODE_SELECT returned with sense %02x/%02x/%02x",
520495
(char *) h->ctlr->array_name, h->ctlr->index,
521496
sense_hdr->sense_key, sense_hdr->asc, sense_hdr->ascq);
522497

523-
done:
524-
return err;
498+
return SCSI_DH_IO;
525499
}
526500

527501
static void send_mode_select(struct work_struct *work)
@@ -530,16 +504,57 @@ static void send_mode_select(struct work_struct *work)
530504
container_of(work, struct rdac_controller, ms_work);
531505
struct scsi_device *sdev = ctlr->ms_sdev;
532506
struct rdac_dh_data *h = sdev->handler_data;
533-
int rc, err, retry_cnt = RDAC_RETRY_COUNT;
507+
int rc, err;
534508
struct rdac_queue_data *tmp, *qdata;
535509
LIST_HEAD(list);
536510
unsigned char cdb[MAX_COMMAND_SIZE];
537511
struct scsi_sense_hdr sshdr;
538512
unsigned int data_size;
539513
blk_opf_t opf = REQ_OP_DRV_OUT | REQ_FAILFAST_DEV |
540514
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER;
515+
struct scsi_failure failure_defs[] = {
516+
{
517+
.sense = NO_SENSE,
518+
.asc = SCMD_FAILURE_ASC_ANY,
519+
.ascq = SCMD_FAILURE_ASCQ_ANY,
520+
.result = SAM_STAT_CHECK_CONDITION,
521+
},
522+
{
523+
.sense = ABORTED_COMMAND,
524+
.asc = SCMD_FAILURE_ASC_ANY,
525+
.ascq = SCMD_FAILURE_ASCQ_ANY,
526+
.result = SAM_STAT_CHECK_CONDITION,
527+
},
528+
{
529+
.sense = UNIT_ATTENTION,
530+
.asc = SCMD_FAILURE_ASC_ANY,
531+
.ascq = SCMD_FAILURE_ASCQ_ANY,
532+
.result = SAM_STAT_CHECK_CONDITION,
533+
},
534+
/* LUN Not Ready and is in the Process of Becoming Ready */
535+
{
536+
.sense = NOT_READY,
537+
.asc = 0x04,
538+
.ascq = 0x01,
539+
.result = SAM_STAT_CHECK_CONDITION,
540+
},
541+
/* Command Lock contention */
542+
{
543+
.sense = ILLEGAL_REQUEST,
544+
.asc = 0x91,
545+
.ascq = 0x36,
546+
.allowed = SCMD_FAILURE_NO_LIMIT,
547+
.result = SAM_STAT_CHECK_CONDITION,
548+
},
549+
{}
550+
};
551+
struct scsi_failures failures = {
552+
.total_allowed = RDAC_RETRY_COUNT,
553+
.failure_definitions = failure_defs,
554+
};
541555
const struct scsi_exec_args exec_args = {
542556
.sshdr = &sshdr,
557+
.failures = &failures,
543558
};
544559

545560
spin_lock(&ctlr->ms_lock);
@@ -548,15 +563,12 @@ static void send_mode_select(struct work_struct *work)
548563
ctlr->ms_sdev = NULL;
549564
spin_unlock(&ctlr->ms_lock);
550565

551-
retry:
552566
memset(cdb, 0, sizeof(cdb));
553567

554568
data_size = rdac_failover_get(ctlr, &list, cdb);
555569

556-
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
557-
"%s MODE_SELECT command",
558-
(char *) h->ctlr->array_name, h->ctlr->index,
559-
(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
570+
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, queueing MODE_SELECT command",
571+
(char *)h->ctlr->array_name, h->ctlr->index);
560572

561573
rc = scsi_execute_cmd(sdev, cdb, opf, &h->ctlr->mode_select, data_size,
562574
RDAC_TIMEOUT * HZ, RDAC_RETRIES, &exec_args);
@@ -570,10 +582,6 @@ static void send_mode_select(struct work_struct *work)
570582
err = SCSI_DH_IO;
571583
} else {
572584
err = mode_select_handle_sense(sdev, &sshdr);
573-
if (err == SCSI_DH_RETRY && retry_cnt--)
574-
goto retry;
575-
if (err == SCSI_DH_IMM_RETRY)
576-
goto retry;
577585
}
578586

579587
list_for_each_entry_safe(qdata, tmp, &list, entry) {

0 commit comments

Comments
 (0)