diff options
| author | Vikram Mulukutla <markivx@codeaurora.org> | 2016-01-06 16:18:02 -0800 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-22 14:44:57 -0700 |
| commit | 3026cbf1d0486b9d56ce512c2d5762c08e27a125 (patch) | |
| tree | 1a4d0e5989fd115841fdc81c8ef9acc163783b53 /kernel/sched | |
| parent | 15dd3b14deac7ee565e3eb5a3e40d35a790dc92c (diff) | |
sched: core: Fix possible hotplug race in set_cpus_allowed_ptr
Since a CPU may go offline after cpu_active_mask is used
to query active CPUs, set_cpus_allowed_ptr might inadverntently
pass an invalid cpu number to move_queued_task.
Fix this by ensuring that the cpumask op that uses cpu_active_mask
checks the return value.
CRs-Fixed: 1029014
Change-Id: Id43a629b40b72cc47773e4027d30953b3a94058d
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
Diffstat (limited to 'kernel/sched')
| -rw-r--r-- | kernel/sched/core.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index aaa4f5e258b1..2fd5c5688dd0 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4477,7 +4477,8 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, if (cpumask_equal(&p->cpus_allowed, new_mask)) goto out; - if (!cpumask_intersects(new_mask, cpu_active_mask)) { + dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); + if (dest_cpu >= nr_cpu_ids) { ret = -EINVAL; goto out; } @@ -4488,7 +4489,6 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, if (cpumask_test_cpu(task_cpu(p), new_mask)) goto out; - dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); if (task_running(rq, p) || p->state == TASK_WAKING) { struct migration_arg arg = { p, dest_cpu }; /* Need help from migration thread: drop lock and wait. */ |
