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>
This commit is contained in:
Vikram Mulukutla 2016-01-06 16:18:02 -08:00 committed by Kyle Yan
parent 15dd3b14de
commit 3026cbf1d0

View file

@ -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. */