scsi: core: No retries on abort success
authorMuneendra Kumar <muneendra.kumar@broadcom.com>
Wed, 6 Jan 2021 21:49:05 +0000 (03:19 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 15 Jan 2021 03:55:17 +0000 (22:55 -0500)
Add a new optional routine, eh_should_retry_cmd(), in scsi_host_template
that allows the transport to decide if a cmd is retryable. Return true if
the transport is in a state the cmd should be retried on.

Update scmd_eh_abort_handler() and scsi_eh_flush_done_q() to both call
scsi_eh_should_retry_cmd() to check whether the command needs to be
retried.

The above changes were based on a patch by Mike Christie.

Link: https://lore.kernel.org/r/1609969748-17684-3-git-send-email-muneendra.kumar@broadcom.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Muneendra Kumar <muneendra.kumar@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_error.c
include/scsi/scsi_host.h

index 28056ee..1cdfa5a 100644 (file)
@@ -124,6 +124,17 @@ static bool scsi_cmd_retry_allowed(struct scsi_cmnd *cmd)
        return ++cmd->retries <= cmd->allowed;
 }
 
+static bool scsi_eh_should_retry_cmd(struct scsi_cmnd *cmd)
+{
+       struct scsi_device *sdev = cmd->device;
+       struct Scsi_Host *host = sdev->host;
+
+       if (host->hostt->eh_should_retry_cmd)
+               return  host->hostt->eh_should_retry_cmd(cmd);
+
+       return true;
+}
+
 /**
  * scmd_eh_abort_handler - Handle command aborts
  * @work:      command to be aborted.
@@ -159,7 +170,8 @@ scmd_eh_abort_handler(struct work_struct *work)
                                                    "eh timeout, not retrying "
                                                    "aborted command\n"));
                        } else if (!scsi_noretry_cmd(scmd) &&
-                                  scsi_cmd_retry_allowed(scmd)) {
+                                  scsi_cmd_retry_allowed(scmd) &&
+                               scsi_eh_should_retry_cmd(scmd)) {
                                SCSI_LOG_ERROR_RECOVERY(3,
                                        scmd_printk(KERN_WARNING, scmd,
                                                    "retry aborted command\n"));
@@ -2111,7 +2123,8 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
        list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
                list_del_init(&scmd->eh_entry);
                if (scsi_device_online(scmd->device) &&
-                   !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd)) {
+                   !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) &&
+                       scsi_eh_should_retry_cmd(scmd)) {
                        SCSI_LOG_ERROR_RECOVERY(3,
                                scmd_printk(KERN_INFO, scmd,
                                             "%s: flush retry cmd\n",
index 701f178..e30fd96 100644 (file)
@@ -314,6 +314,12 @@ struct scsi_host_template {
         * Status: OPTIONAL
         */
        enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *);
+       /*
+        * Optional routine that allows the transport to decide if a cmd
+        * is retryable. Return true if the transport is in a state the
+        * cmd should be retried on.
+        */
+       bool (*eh_should_retry_cmd)(struct scsi_cmnd *scmd);
 
        /* This is an optional routine that allows transport to initiate
         * LLD adapter or firmware reset using sysfs attribute.