scsi: core: Ensure that the SCSI error handler gets woken up
[platform/kernel/linux-exynos.git] / drivers / scsi / scsi_error.c
index dab876c..fa504ba 100644 (file)
@@ -220,6 +220,17 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd)
        }
 }
 
+static void scsi_eh_inc_host_failed(struct rcu_head *head)
+{
+       struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu);
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       shost->host_failed++;
+       scsi_eh_wakeup(shost);
+       spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
 /**
  * scsi_eh_scmd_add - add scsi cmd to error handling.
  * @scmd:      scmd to run eh on.
@@ -242,9 +253,12 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd)
 
        scsi_eh_reset(scmd);
        list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
-       shost->host_failed++;
-       scsi_eh_wakeup(shost);
        spin_unlock_irqrestore(shost->host_lock, flags);
+       /*
+        * Ensure that all tasks observe the host state change before the
+        * host_failed change.
+        */
+       call_rcu(&shost->rcu, scsi_eh_inc_host_failed);
 }
 
 /**