scsi: smartpqi: Shorten drive visibility after removal
authorMike McGowen <Mike.McGowen@microchip.com>
Fri, 8 Jul 2022 18:46:50 +0000 (13:46 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 14 Jul 2022 03:42:02 +0000 (23:42 -0400)
Check the response code returned from the LUN reset task management
function and if it indicates the LUN is not valid, do not retry.

Reduce rescan worker delay to 5 seconds for the event handler only.

The removal of a drive from the OS could have been delayed up to 30 seconds
after being physically pulled.

The driver was retrying a LUN reset 3 times even though the return code
indiciated the LUN was no longer valid. There was a 10 second delay between
each retry. Additionally, the rescan worker was scheduled to run 10 seconds
after the driver received the event.

Link: https://lore.kernel.org/r/165730601025.177165.9416869335174437006.stgit@brunhilda
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
Signed-off-by: Mike McGowen <Mike.McGowen@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.h
drivers/scsi/smartpqi/smartpqi_init.c

index 2e40320129c08b15d08c44d0560005c4258fdb42..49895c6ca64c7565ef63fb535b5a427a8f4b21aa 100644 (file)
@@ -708,6 +708,7 @@ typedef u32 pqi_index_t;
 #define SOP_TMF_COMPLETE               0x0
 #define SOP_TMF_REJECTED               0x4
 #define SOP_TMF_FUNCTION_SUCCEEDED     0x8
+#define SOP_RC_INCORRECT_LOGICAL_UNIT  0x9
 
 /* additional CDB bytes usage field codes */
 #define SOP_ADDITIONAL_CDB_BYTES_0     0       /* 16-byte CDB */
index 7c0d069a315831fd68c7a8219318818be37a08d1..fa5cd2dfa3ad916ca3fc9ac30f2d75520625b84e 100644 (file)
@@ -3322,6 +3322,9 @@ static int pqi_interpret_task_management_response(struct pqi_ctrl_info *ctrl_inf
        case SOP_TMF_REJECTED:
                rc = -EAGAIN;
                break;
+       case SOP_RC_INCORRECT_LOGICAL_UNIT:
+               rc = -ENODEV;
+               break;
        default:
                rc = -EIO;
                break;
@@ -3697,8 +3700,11 @@ static void pqi_event_worker(struct work_struct *work)
                event++;
        }
 
+#define PQI_RESCAN_WORK_FOR_EVENT_DELAY                (5 * HZ)
+
        if (rescan_needed)
-               pqi_schedule_rescan_worker_delayed(ctrl_info);
+               pqi_schedule_rescan_worker_with_delay(ctrl_info,
+                       PQI_RESCAN_WORK_FOR_EVENT_DELAY);
 
 out:
        pqi_ctrl_unbusy(ctrl_info);
@@ -6256,7 +6262,7 @@ static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct pq
 
        for (retries = 0;;) {
                reset_rc = pqi_lun_reset(ctrl_info, device);
-               if (reset_rc == 0 || ++retries > PQI_LUN_RESET_RETRIES)
+               if (reset_rc == 0 || reset_rc == -ENODEV || ++retries > PQI_LUN_RESET_RETRIES)
                        break;
                msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS);
        }