]> www.infradead.org Git - users/willy/xarray.git/commitdiff
scsi: core: Have SCSI midlayer retry scsi_report_lun_scan() errors
authorMike Christie <michael.christie@oracle.com>
Tue, 23 Jan 2024 00:22:14 +0000 (18:22 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 30 Jan 2024 02:20:54 +0000 (21:20 -0500)
This has scsi_report_lun_scan() have the SCSI midlayer retry errors instead
of driving them itself.

There is one behavior change where we no longer retry when
scsi_execute_cmd() returns < 0, but we should be ok. We don't need to retry
for failures like the queue being removed, and for the case where there are
no tags/reqs the block layer waits/retries for us. For possible memory
allocation failures from blk_rq_map_kern() we use GFP_NOIO, so retrying
will probably not help.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20240123002220.129141-14-michael.christie@oracle.com
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_scan.c

index 8ded08f37337e38bbbb5f34cdc011cbfa28830fa..70c0319be34cdb148c4989d97a9abada67fb286b 100644 (file)
@@ -1416,14 +1416,34 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
        unsigned int length;
        u64 lun;
        unsigned int num_luns;
-       unsigned int retries;
        int result;
        struct scsi_lun *lunp, *lun_data;
-       struct scsi_sense_hdr sshdr;
        struct scsi_device *sdev;
        struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct scsi_failure failure_defs[] = {
+               {
+                       .sense = UNIT_ATTENTION,
+                       .asc = SCMD_FAILURE_ASC_ANY,
+                       .ascq = SCMD_FAILURE_ASCQ_ANY,
+                       .result = SAM_STAT_CHECK_CONDITION,
+               },
+               /* Fail all CCs except the UA above */
+               {
+                       .sense = SCMD_FAILURE_SENSE_ANY,
+                       .result = SAM_STAT_CHECK_CONDITION,
+               },
+               /* Retry any other errors not listed above */
+               {
+                       .result = SCMD_FAILURE_RESULT_ANY,
+               },
+               {}
+       };
+       struct scsi_failures failures = {
+               .total_allowed = 3,
+               .failure_definitions = failure_defs,
+       };
        const struct scsi_exec_args exec_args = {
-               .sshdr = &sshdr,
+               .failures = &failures,
        };
        int ret = 0;
 
@@ -1494,29 +1514,18 @@ retry:
         * should come through as a check condition, and will not generate
         * a retry.
         */
-       for (retries = 0; retries < 3; retries++) {
-               SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
-                               "scsi scan: Sending REPORT LUNS to (try %d)\n",
-                               retries));
-
-               result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN,
-                                         lun_data, length,
-                                         SCSI_REPORT_LUNS_TIMEOUT, 3,
-                                         &exec_args);
+       scsi_failures_reset_retries(&failures);
 
-               SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
-                               "scsi scan: REPORT LUNS"
-                               " %s (try %d) result 0x%x\n",
-                               result ?  "failed" : "successful",
-                               retries, result));
-               if (result == 0)
-                       break;
-               else if (scsi_sense_valid(&sshdr)) {
-                       if (sshdr.sense_key != UNIT_ATTENTION)
-                               break;
-               }
-       }
+       SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+                         "scsi scan: Sending REPORT LUNS\n"));
+
+       result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, lun_data,
+                                 length, SCSI_REPORT_LUNS_TIMEOUT, 3,
+                                 &exec_args);
 
+       SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+                         "scsi scan: REPORT LUNS  %s result 0x%x\n",
+                         result ?  "failed" : "successful", result));
        if (result) {
                /*
                 * The device probably does not support a REPORT LUN command