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.


---

 25-akpm/kernel/sched.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)

diff -puN kernel/sched.c~sched-kthread_stop_race_fix kernel/sched.c
--- 25/kernel/sched.c~sched-kthread_stop_race_fix	2004-04-30 20:06:34.133124360 -0700
+++ 25-akpm/kernel/sched.c	2004-04-30 20:06:34.138123600 -0700
@@ -3379,6 +3379,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;
@@ -3400,10 +3401,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);
@@ -3424,6 +3425,7 @@ static int migration_thread(void * data)
 
 		complete(&req->done);
 	}
+	__set_current_state(TASK_RUNNING);
 	return 0;
 
 wait_to_die:

_