cgroup/cpuset: Properly disabling partition when partition state switching fails

Before commit 103b08709e ("cgroup/cpuset: Fail if isolated and nohz_full
don't leave any housekeeping"), the partition state can be freely switched
from "root" to "isolated" and vice versa. After that commit, the switch
from "root" to "isolated" can fail if it exhausts all the housekeeping
CPUs. Later on, the switch from "isolated" to "root" can also fail if
some of the partition CPUs are boot-time isolated by "isolcpus".

A local or remote partition is made invalid when the switch fails.
However there are 2 problems with the existing invalidation code.

 1) Both the subpartitions_cpus and isolated_cpus are not properly
    updated.
 2) In the case of remote partition with remote_partition flag set, it
    is not cleared.

Fix this by calling the proper partition disabling function in this case.

On an x86 test system with boot option "isolcpus=10 cgroup_debug" set
and more than 16 cores, the following commands were executed after boot.

  # cd /sys/fs/cgroup
  # echo +cpuset > cgroup.subtree_control
  # cat cpuset.cpus.isolated
  10
  # mkdir A
  # echo 10-12 > A/cpuset.cpus
  # echo isolated > A/cpuset.cpus.partition
  # cat A/cpuset.cpus.partition
  isolated

Before the patch:

  # echo root > A/cpuset.cpus.partition
  # cat A/cpuset.cpus.partition
  root invalid (partition config conflicts with housekeeping setup)
  # cat cpuset.cpus.isolated .__DEBUG__.cpuset.cpus.subpartitions
  10-12
  10-12

After the patch:

  # echo root > A/cpuset.cpus.partition
  # cat A/cpuset.cpus.partition
  root invalid (partition config conflicts with housekeeping setup)
  # cat cpuset.cpus.isolated .__DEBUG__.cpuset.cpus.subpartitions
  10

Reported-by: Tejun Heo <tj@kernel.org>
Link: https://lore.kernel.org/lkml/7f4c57b26ad120ab30adf35653f1dd94@kernel.org/
Fixes: 4a74e41888 ("cgroup/cpuset: Check partition conflict with housekeeping setup")
Fixes: 103b08709e ("cgroup/cpuset: Fail if isolated and nohz_full don't leave any housekeeping")
Reviewed-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Waiman Long 2026-10-19 14:10:16 -04:00 committed by Tejun Heo
parent 2c0a5742fc
commit db27a748a3

View File

@ -2928,6 +2928,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
struct cpuset *parent = parent_cs(cs);
struct tmpmasks tmpmask;
bool isolcpus_updated = false;
bool disable_partition = false;
if (old_prs == new_prs)
return 0;
@ -2984,15 +2985,21 @@ static int update_prstate(struct cpuset *cs, int new_prs)
* Need to update isolated_cpus.
*/
if (prstate_housekeeping_conflict(new_prs, parent_prs,
cs->effective_xcpus, NULL))
cs->effective_xcpus, NULL)) {
disable_partition = true;
err = PERR_HKEEPING;
else
} else {
isolcpus_updated = true;
}
} else {
/*
* Switching back to member is always allowed even if it
* disables child partitions.
*/
disable_partition = true;
}
if (disable_partition) {
if (is_remote_partition(cs))
remote_partition_disable(cs, &tmpmask);
else
@ -3001,7 +3008,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
/*
* Invalidation of child partitions will be done in
* update_cpumasks_hier().
* update_cpumasks_hier() below.
*/
}
out:
@ -3020,8 +3027,8 @@ static int update_prstate(struct cpuset *cs, int new_prs)
isolated_cpus_update(old_prs, new_prs, cs->effective_xcpus);
spin_unlock_irq(&callback_lock);
/* Force update if switching back to member & update effective_xcpus */
update_cpumasks_hier(cs, &tmpmask, !new_prs);
/* Force update if partition is disabled & update effective_xcpus */
update_cpumasks_hier(cs, &tmpmask, disable_partition);
/* A newly created partition must have effective_xcpus set */
WARN_ON_ONCE(!old_prs && (new_prs > 0)