From 1329b6abc196900eb04d9bde358a313c945d54e9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 18 Mar 2004 16:03:06 -0800 Subject: [PATCH] [PATCH] Hotplug CPUs: Keep IRQs off in Migration Thread Calling 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 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 3097153d43a03..f3fc4fe276620 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -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; -- 2.53.0