cgroup/cpuset: Include offline CPUs when tasks' cpumasks in top_cpuset are updated
authorWaiman Long <longman@redhat.com>
Fri, 17 Mar 2023 15:15:07 +0000 (11:15 -0400)
committerTejun Heo <tj@kernel.org>
Wed, 29 Mar 2023 18:42:09 +0000 (08:42 -1000)
Similar to commit 3fb906e7fabb ("group/cpuset: Don't filter offline
CPUs in cpuset_cpus_allowed() for top cpuset tasks"), the whole set of
possible CPUs including offline ones should be used for setting cpumasks
for tasks in the top cpuset when a cpuset partition is modified as the
hotplug code won't update cpumasks for tasks in the top cpuset when
CPUs become online or offline.

Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/cgroup/cpuset.c

index a05bc93..bc4dcfd 100644 (file)
@@ -1209,7 +1209,9 @@ void rebuild_sched_domains(void)
  *
  * Iterate through each task of @cs updating its cpus_allowed to the
  * effective cpuset's.  As this function is called with cpuset_rwsem held,
- * cpuset membership stays stable.
+ * cpuset membership stays stable. For top_cpuset, task_cpu_possible_mask()
+ * is used instead of effective_cpus to make sure all offline CPUs are also
+ * included as hotplug code won't update cpumasks for tasks in top_cpuset.
  */
 static void update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus)
 {
@@ -1219,15 +1221,18 @@ static void update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus)
 
        css_task_iter_start(&cs->css, 0, &it);
        while ((task = css_task_iter_next(&it))) {
-               /*
-                * Percpu kthreads in top_cpuset are ignored
-                */
-               if (top_cs && (task->flags & PF_KTHREAD) &&
-                   kthread_is_per_cpu(task))
-                       continue;
+               const struct cpumask *possible_mask = task_cpu_possible_mask(task);
 
-               cpumask_and(new_cpus, cs->effective_cpus,
-                           task_cpu_possible_mask(task));
+               if (top_cs) {
+                       /*
+                        * Percpu kthreads in top_cpuset are ignored
+                        */
+                       if ((task->flags & PF_KTHREAD) && kthread_is_per_cpu(task))
+                               continue;
+                       cpumask_andnot(new_cpus, possible_mask, cs->subparts_cpus);
+               } else {
+                       cpumask_and(new_cpus, possible_mask, cs->effective_cpus);
+               }
                set_cpus_allowed_ptr(task, new_cpus);
        }
        css_task_iter_end(&it);