]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Hotplug CPUs: Keep IRQs off in Migration Thread Calling
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 19 Mar 2004 00:03:06 +0000 (16:03 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 19 Mar 2004 00:03:06 +0000 (16:03 -0800)
Currently the migration thread re-enables irqs, then calls
move_task_away which disables IRQs again and actually does the move.
This means there is a race where the migration thread gets preempted,
and the target CPU can go down.

Hold irqs disabled in migration thread across move_task_away(), which
now doesn't need to save flags (the other caller is the hotplug CPU
code, where irqs are also disabled).

kernel/sched.c

index 3097153d43a03f6bdd8dec284604dc28fb1f66da..f3fc4fe27662061e37941253c250e83d76aed387 100644 (file)
@@ -2733,11 +2733,9 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed);
 static void move_task_away(struct task_struct *p, int dest_cpu)
 {
        runqueue_t *rq_dest;
-       unsigned long flags;
 
        rq_dest = cpu_rq(dest_cpu);
 
-       local_irq_save(flags);
        double_rq_lock(this_rq(), rq_dest);
        if (task_cpu(p) != smp_processor_id())
                goto out; /* Already moved */
@@ -2753,7 +2751,6 @@ static void move_task_away(struct task_struct *p, int dest_cpu)
 
 out:
        double_rq_unlock(this_rq(), rq_dest);
-       local_irq_restore(flags);
 }
 
 /*
@@ -2792,10 +2789,11 @@ static int migration_thread(void * data)
                }
                req = list_entry(head->next, migration_req_t, list);
                list_del_init(head->next);
-               spin_unlock_irq(&rq->lock);
+               spin_unlock(&rq->lock);
 
                move_task_away(req->task,
                               any_online_cpu(req->task->cpus_allowed));
+               local_irq_enable();
                complete(&req->done);
        }
        return 0;