[PATCH] scsi_error thread exits in TASK_INTERRUPTIBLE state.
[deliverable/linux.git] / drivers / scsi / scsi_error.c
index af589fac814d9090d293e04587ed9fb494c1be37..52b348c36d56b7cc4be4a03e444e8ad182679620 100644 (file)
@@ -50,7 +50,7 @@
 void scsi_eh_wakeup(struct Scsi_Host *shost)
 {
        if (shost->host_busy == shost->host_failed) {
-               up(shost->eh_wait);
+               wake_up_process(shost->ehandler);
                SCSI_LOG_ERROR_RECOVERY(5,
                                printk("Waking error handler thread\n"));
        }
@@ -70,7 +70,7 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
        unsigned long flags;
        int ret = 0;
 
-       if (shost->eh_wait == NULL)
+       if (!shost->ehandler)
                return 0;
 
        spin_lock_irqsave(shost->host_lock, flags);
@@ -1591,40 +1591,31 @@ int scsi_error_handler(void *data)
 {
        struct Scsi_Host *shost = (struct Scsi_Host *) data;
        int rtn;
-       DECLARE_MUTEX_LOCKED(sem);
 
        current->flags |= PF_NOFREEZE;
-       shost->eh_wait = &sem;
 
+       
        /*
-        * Wake up the thread that created us.
+        * Note - we always use TASK_INTERRUPTIBLE even if the module
+        * was loaded as part of the kernel.  The reason is that
+        * UNINTERRUPTIBLE would cause this thread to be counted in
+        * the load average as a running process, and an interruptible
+        * wait doesn't.
         */
-       SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
-                                         " scsi_eh_%d\n",shost->host_no));
-
-       while (1) {
-               /*
-                * If we get a signal, it means we are supposed to go
-                * away and die.  This typically happens if the user is
-                * trying to unload a module.
-                */
-               SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
-                                                 " scsi_eh_%d"
-                                                 " sleeping\n",shost->host_no));
-
-               /*
-                * Note - we always use down_interruptible with the semaphore
-                * even if the module was loaded as part of the kernel.  The
-                * reason is that down() will cause this thread to be counted
-                * in the load average as a running process, and down
-                * interruptible doesn't.  Given that we need to allow this
-                * thread to die if the driver was loaded as a module, using
-                * semaphores isn't unreasonable.
-                */
-               down_interruptible(&sem);
-               if (kthread_should_stop())
-                       break;
+       set_current_state(TASK_INTERRUPTIBLE);
+       while (!kthread_should_stop()) {
+               if (shost->host_failed == 0 ||
+                   shost->host_failed != shost->host_busy) {
+                       SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
+                                                         " scsi_eh_%d"
+                                                         " sleeping\n",
+                                                         shost->host_no));
+                       schedule();
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       continue;
+               }
 
+               __set_current_state(TASK_RUNNING);
                SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
                                                  " scsi_eh_%d waking"
                                                  " up\n",shost->host_no));
@@ -1651,16 +1642,18 @@ int scsi_error_handler(void *data)
                 * which are still online.
                 */
                scsi_restart_operations(shost);
-
+               set_current_state(TASK_INTERRUPTIBLE);
        }
 
+       __set_current_state(TASK_RUNNING);
+
        SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"
                                          " exiting\n",shost->host_no));
 
        /*
         * Make sure that nobody tries to wake us up again.
         */
-       shost->eh_wait = NULL;
+       shost->ehandler = NULL;
        return 0;
 }
 
This page took 0.026187 seconds and 5 git commands to generate.