aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Adamushko <[email protected]>2008-07-10 00:32:40 +0200
committerIngo Molnar <[email protected]>2008-07-10 09:35:34 +0200
commitdc7fab8b3bb388c57c6c4a43ba68c8a32ca25204 (patch)
tree4f96ecc3625b3af71d00592f0e47841b8ab849a7
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 <[email protected]> Cc: [email protected] Cc: Lai Jiangshan <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Avi Kivity <[email protected]> Cc: Andrew Morton <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
-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)
double_rq_lock(rq_src, rq_dest);
/* Already moved. */
- if (task_cpu(p) != src_cpu)
+ if (task_cpu(p) != src_cpu) {
+ ret = 1;
goto out;
+ }
/* Affinity changed (again). */
if (!cpu_isset(dest_cpu, p->cpus_allowed))
goto out;