scsi: smartpqi: Quickly propagate path failures to SCSI midlayer
authorMurthy Bhat <Murthy.Bhat@microchip.com>
Tue, 1 Feb 2022 21:48:13 +0000 (15:48 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 8 Feb 2022 04:38:34 +0000 (23:38 -0500)
Return DID_NO_CONNECT when a path failure is detected.

When a path fails during I/O and AIO path gets disabled for a multipath
device, the I/O was retried in the RAID path slowing down path fail
detection. Returning DID_NO_CONNECT allows multipath to switch paths more
quickly.

Link: https://lore.kernel.org/r/164375209313.440833.9992416628621839233.stgit@brunhilda.pdev.net
Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Reviewed-by: Sagar Biradar <sagar.biradar@microchip.com>
Signed-off-by: Murthy Bhat <Murthy.Bhat@microchip.com>
Signed-off-by: Don Brace <don.brace@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/smartpqi/smartpqi_init.c

index f51605c..9bc2987 100644 (file)
@@ -2291,6 +2291,14 @@ static inline bool pqi_is_device_with_sas_address(struct pqi_scsi_dev *device)
        return false;
 }
 
+static inline bool pqi_is_multipath_device(struct pqi_scsi_dev *device)
+{
+       if (pqi_is_logical_device(device))
+               return false;
+
+       return (device->path_map & (device->path_map - 1)) != 0;
+}
+
 static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
 {
        return !device->is_physical_device || !pqi_skip_device(device->scsi3addr);
@@ -3216,12 +3224,14 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
        int residual_count;
        int xfer_count;
        bool device_offline;
+       struct pqi_scsi_dev *device;
 
        scmd = io_request->scmd;
        error_info = io_request->error_info;
        host_byte = DID_OK;
        sense_data_length = 0;
        device_offline = false;
+       device = scmd->device->hostdata;
 
        switch (error_info->service_response) {
        case PQI_AIO_SERV_RESPONSE_COMPLETE:
@@ -3246,8 +3256,14 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
                        break;
                case PQI_AIO_STATUS_AIO_PATH_DISABLED:
                        pqi_aio_path_disabled(io_request);
-                       scsi_status = SAM_STAT_GOOD;
-                       io_request->status = -EAGAIN;
+                       if (pqi_is_multipath_device(device)) {
+                               pqi_device_remove_start(device);
+                               host_byte = DID_NO_CONNECT;
+                               scsi_status = SAM_STAT_CHECK_CONDITION;
+                       } else {
+                               scsi_status = SAM_STAT_GOOD;
+                               io_request->status = -EAGAIN;
+                       }
                        break;
                case PQI_AIO_STATUS_NO_PATH_TO_DEVICE:
                case PQI_AIO_STATUS_INVALID_DEVICE: