aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorDmitry Adamushko <dmitry.adamushko@gmail.com>2008-07-09 18:32:40 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-10 03:35:34 -0400
commitdc7fab8b3bb388c57c6c4a43ba68c8a32ca25204 (patch)
tree4f96ecc3625b3af71d00592f0e47841b8ab849a7 /kernel/sched.c
parent619b0488038224391e64fa03854651ca0f5efe56 (diff)
sched: fix cpu hotplug
I think we may have a race between try_to_wake_up() and migrate_live_tasks() -> move_task_off_dead_cpu() when the later one may end up looping endlessly. Interrupts are enabled on other CPUs when migration_call(CPU_DEAD, ...) is called so we may get a race between try_to_wake_up() and migrate_live_tasks() -> move_task_off_dead_cpu(). The former one may push a task out of a dead CPU causing the later one to loop endlessly. Heiko Carstens observed: | That's exactly what explains a dump I got yesterday. Thanks for fixing! :) Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com> Cc: miaox@cn.fujitsu.com Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Avi Kivity <avi@qumranet.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 94ead43eda62..9397b8710138 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5621,8 +5621,10 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
5621 5621
5622 double_rq_lock(rq_src, rq_dest); 5622 double_rq_lock(rq_src, rq_dest);
5623 /* Already moved. */ 5623 /* Already moved. */
5624 if (task_cpu(p) != src_cpu) 5624 if (task_cpu(p) != src_cpu) {
5625 ret = 1;
5625 goto out; 5626 goto out;
5627 }
5626 /* Affinity changed (again). */ 5628 /* Affinity changed (again). */
5627 if (!cpu_isset(dest_cpu, p->cpus_allowed)) 5629 if (!cpu_isset(dest_cpu, p->cpus_allowed))
5628 goto out; 5630 goto out;