diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2008-07-09 18:32:40 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-10 03:35:34 -0400 |
commit | dc7fab8b3bb388c57c6c4a43ba68c8a32ca25204 (patch) | |
tree | 4f96ecc3625b3af71d00592f0e47841b8ab849a7 /kernel/sched.c | |
parent | 619b0488038224391e64fa03854651ca0f5efe56 (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.c | 4 |
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; |