scsi: core: Move scsi_host_busy() out of host lock if it is for per-command
[platform/kernel/linux-starfive.git] / drivers / scsi / scsi_error.c
index c67cdcd..43eff11 100644 (file)
@@ -61,11 +61,11 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd);
 static enum scsi_disposition scsi_try_to_abort_cmd(const struct scsi_host_template *,
                                                   struct scsi_cmnd *);
 
-void scsi_eh_wakeup(struct Scsi_Host *shost)
+void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy)
 {
        lockdep_assert_held(shost->host_lock);
 
-       if (scsi_host_busy(shost) == shost->host_failed) {
+       if (busy == shost->host_failed) {
                trace_scsi_eh_wakeup(shost);
                wake_up_process(shost->ehandler);
                SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost,
@@ -88,7 +88,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost)
        if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 ||
            scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) {
                shost->host_eh_scheduled++;
-               scsi_eh_wakeup(shost);
+               scsi_eh_wakeup(shost, scsi_host_busy(shost));
        }
 
        spin_unlock_irqrestore(shost->host_lock, flags);
@@ -282,11 +282,12 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head)
 {
        struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
        struct Scsi_Host *shost = scmd->device->host;
+       unsigned int busy = scsi_host_busy(shost);
        unsigned long flags;
 
        spin_lock_irqsave(shost->host_lock, flags);
        shost->host_failed++;
-       scsi_eh_wakeup(shost);
+       scsi_eh_wakeup(shost, busy);
        spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
@@ -1152,6 +1153,7 @@ retry:
 
        scsi_log_send(scmd);
        scmd->submitter = SUBMITTED_BY_SCSI_ERROR_HANDLER;
+       scmd->flags |= SCMD_LAST;
 
        /*
         * Lock sdev->state_mutex to avoid that scsi_device_quiesce() can
@@ -2195,15 +2197,18 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
        struct scsi_cmnd *scmd, *next;
 
        list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
+               struct scsi_device *sdev = scmd->device;
+
                list_del_init(&scmd->eh_entry);
-               if (scsi_device_online(scmd->device) &&
-                   !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) &&
-                       scsi_eh_should_retry_cmd(scmd)) {
+               if (scsi_device_online(sdev) && !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",
                                             current->comm));
                                scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
+                               blk_mq_kick_requeue_list(sdev->request_queue);
                } else {
                        /*
                         * If just we got sense for the device (called
@@ -2459,6 +2464,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
        scsi_init_command(dev, scmd);
 
        scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL;
+       scmd->flags |= SCMD_LAST;
        memset(&scmd->sdb, 0, sizeof(scmd->sdb));
 
        scmd->cmd_len                   = 0;