aboutsummaryrefslogtreecommitdiff
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorMike Galbraith <efault@gmx.de>2010-08-26 05:29:16 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-20 13:17:45 -0700
commit8c5217d732d576bcdacf7cd515165f246e6a4912 (patch)
tree766d33890ae073a66e7ebf3e26d12aa81c1e027f /kernel/sched.c
parent6f6198a78a34e3d8623f717d05087267e8dedef2 (diff)
sched: revert stable c6fc81a sched: Fix a race between ttwu() and migrate_task()
This commit does not appear to have been meant for 32-stable, and causes ltp's cpusets testcases to fail, revert it. Original commit text: sched: Fix a race between ttwu() and migrate_task() Based on commit e2912009fb7b715728311b0d8fe327a1432b3f79 upstream, but done differently as this issue is not present in .33 or .34 kernels due to rework in this area. If a task is in the TASK_WAITING state, then try_to_wake_up() is working on it, and it will place it on the correct cpu. This commit ensures that neither migrate_task() nor __migrate_task() calls set_task_cpu(p) while p is in the TASK_WAKING state. Otherwise, there could be two concurrent calls to set_task_cpu(p), resulting in the task's cfs_rq being inconsistent with its cpu. Signed-off-by: Mike Galbraith <efault@gmx.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index ba2d610f452..48f8dc07648 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2123,10 +2123,12 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
/*
* If the task is not on a runqueue (and not running), then
- * the next wake-up will properly place the task.
+ * it is sufficient to simply update the task's cpu field.
*/
- if (!p->se.on_rq && !task_running(rq, p))
+ if (!p->se.on_rq && !task_running(rq, p)) {
+ set_task_cpu(p, dest_cpu);
return 0;
+ }
init_completion(&req->done);
req->task = p;
@@ -7217,9 +7219,6 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
/* Already moved. */
if (task_cpu(p) != src_cpu)
goto done;
- /* Waking up, don't get in the way of try_to_wake_up(). */
- if (p->state == TASK_WAKING)
- goto fail;
/* Affinity changed (again). */
if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed))
goto fail;