]> git.hungrycats.org Git - linux/commitdiff
[PATCH] migration_thread() race fix
authorAndrew Morton <akpm@osdl.org>
Mon, 10 May 2004 06:30:22 +0000 (23:30 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 10 May 2004 06:30:22 +0000 (23:30 -0700)
From: Srivatsa Vaddagiri <vatsa@in.ibm.com>

Noticed that migration_thread can examine "kthread_should_stop()?" without
setting its state to TASK_INTERRUPTIBLE first.  This can cause kthread_stop
on that thread to block forever ...

P.S  - I assumed that having the task state set to TASK_INTERRUTIBLE
  while it is doing active_load_balance is fine. It seemed to be
  the case earlier also.

kernel/sched.c

index 422bfeb614e1eee4b259b96652af41fd479e3b94..d083166dd3f0a6f3804d191d48305156171b4d28 100644 (file)
@@ -3372,6 +3372,7 @@ static int migration_thread(void * data)
        rq = cpu_rq(cpu);
        BUG_ON(rq->migration_thread != current);
 
+       set_current_state(TASK_INTERRUPTIBLE);
        while (!kthread_should_stop()) {
                struct list_head *head;
                migration_req_t *req;
@@ -3393,10 +3394,10 @@ static int migration_thread(void * data)
 
                head = &rq->migration_queue;
 
-               current->state = TASK_INTERRUPTIBLE;
                if (list_empty(head)) {
                        spin_unlock_irq(&rq->lock);
                        schedule();
+                       set_current_state(TASK_INTERRUPTIBLE);
                        continue;
                }
                req = list_entry(head->next, migration_req_t, list);
@@ -3417,6 +3418,7 @@ static int migration_thread(void * data)
 
                complete(&req->done);
        }
+       __set_current_state(TASK_RUNNING);
        return 0;
 
 wait_to_die: