Whamcloud - gitweb
as Zach's pointed out, fix the potential deadlock, use
authornfshp <nfshp>
Sat, 14 Dec 2002 12:05:49 +0000 (12:05 +0000)
committernfshp <nfshp>
Sat, 14 Dec 2002 12:05:49 +0000 (12:05 +0000)
wait_event() to sync between threads when liod start/stop.

lustre/llite/iod.c

index c748064..a2f58c6 100644 (file)
@@ -34,18 +34,16 @@ static int liod_main(void *arg)
         sprintf(current->comm, "liod");
         unlock_kernel();
 
-        /* declear we are ready */
-       spin_lock(&iod->io_lock);
-       iod->io_flag |= LIOD_FLAG_ALIVE;
+        /* declare we are ready */
+       set_bit(LIOD_FLAG_ALIVE, &iod->io_flag);
         wake_up(&iod->io_waitq);
-       spin_unlock(&iod->io_lock);
 
         CDEBUG(D_NET, "liod(%d) started\n", current->pid);
         while (1) {
                int t;
 
                /* check the stop command */
-               if (iod->io_flag & LIOD_FLAG_STOP)
+               if (test_bit(LIOD_FLAG_STOP, &iod->io_flag))
                        break;
 
                t = interruptible_sleep_on_timeout(&iod->io_sleepq,
@@ -54,11 +52,8 @@ static int liod_main(void *arg)
                                (t ? "wakeup" : "timeout"));
         }
 
-       spin_lock(&iod->io_lock);
-       iod->io_flag &= ~LIOD_FLAG_ALIVE;
-       iod->io_flag |= LIOD_FLAG_STOPPED;
+       clear_bit(LIOD_FLAG_ALIVE, &iod->io_flag);
         wake_up(&iod->io_waitq);
-       spin_unlock(&iod->io_lock);
 
         CDEBUG(D_NET, "liod(%d) exit\n", current->pid);
         RETURN(0);
@@ -66,40 +61,25 @@ static int liod_main(void *arg)
 
 int liod_start(struct ll_io_daemon *iod)
 {
-        DECLARE_WAITQUEUE(queue, current);
         int rc;
 
         /* initialize */
         iod->io_flag = 0;
-        spin_lock_init(&iod->io_lock);
         init_waitqueue_head(&iod->io_sleepq);
         init_waitqueue_head(&iod->io_waitq);
 
-        spin_lock(&iod->io_lock);
-
         rc = kernel_thread(liod_main, (void *) iod,
                            CLONE_VM | CLONE_FS | CLONE_FILES);
 
         if (rc < 0) {
                CERROR("fail to start liod, error %d\n", rc);
-                spin_unlock(&iod->io_lock);
                 return rc;
         }
 
-        set_current_state(TASK_UNINTERRUPTIBLE);
-        add_wait_queue(&iod->io_waitq, &queue);
-        spin_unlock(&iod->io_lock);
-
        /* wait liod start */
-        schedule();
-
-        set_current_state(TASK_RUNNING);
-        remove_wait_queue(&iod->io_waitq, &queue);
+       wait_event(iod->io_waitq, test_bit(LIOD_FLAG_ALIVE, &iod->io_flag));
 
-        if (iod->io_flag & LIOD_FLAG_ALIVE)
-                return 0;
-        else
-                return -ENOMEM;
+        return 0;
 }
 
 void liod_wakeup(struct ll_io_daemon *iod)
@@ -109,23 +89,19 @@ void liod_wakeup(struct ll_io_daemon *iod)
 
 void liod_stop(struct ll_io_daemon *iod)
 {
-        DECLARE_WAITQUEUE(queue, current);
-
-        spin_lock(&iod->io_lock);
+       if (!test_bit(LIOD_FLAG_ALIVE, &iod->io_flag)) {
+               CERROR("liod died unexpectedly!\n");
+               return;
+       }
 
         /* send the kill command */
-        iod->io_flag |= LIOD_FLAG_STOP;
+       set_bit(LIOD_FLAG_STOP, &iod->io_flag);
 
         /* if wakeup daemon */
         wake_up(&iod->io_sleepq);
 
-        /* wait daemon's exit */
-        set_current_state(TASK_UNINTERRUPTIBLE);
-        add_wait_queue(&iod->io_waitq, &queue);
-        spin_unlock(&iod->io_lock);
-
-        schedule();
-        /* must woken up by liod */
+       /* wait liod exit */
+       wait_event(iod->io_waitq, !test_bit(LIOD_FLAG_ALIVE, &iod->io_flag));
 
        return;
 }