diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 1da5f4980b92..a373654da841 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -378,12 +378,15 @@ static inline bool is_in_v2_mode(void) static void guarantee_online_cpus(struct task_struct *tsk, struct cpumask *pmask) { - struct cpuset *cs = task_cs(tsk); const struct cpumask *possible_mask = task_cpu_possible_mask(tsk); + struct cpuset *cs; if (WARN_ON(!cpumask_and(pmask, possible_mask, cpu_active_mask))) cpumask_copy(pmask, cpu_active_mask); + rcu_read_lock(); + cs = task_cs(tsk); + while (!cpumask_intersects(cs->effective_cpus, pmask)) { cs = parent_cs(cs); if (unlikely(!cs)) { @@ -394,10 +397,13 @@ static void guarantee_online_cpus(struct task_struct *tsk, * cpuset's effective_cpus is on its way to be * identical to cpu_online_mask. */ - return; + goto out_unlock; } } cpumask_and(pmask, pmask, cs->effective_cpus); + +out_unlock: + rcu_read_unlock(); } /*