From 3026cbf1d0486b9d56ce512c2d5762c08e27a125 Mon Sep 17 00:00:00 2001 From: Vikram Mulukutla Date: Wed, 6 Jan 2016 16:18:02 -0800 Subject: [PATCH] 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 --- kernel/sched/core.c | 4 ++-- 1 file 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. */