在 2026/10/14 22:05, Waiman Long 写道:
> It is found that when a local isolated partition is being invalidated
> because its root partition parent is no longer valid, the isolated_cpus
> cpumask may not be properly updated. If the parent was previously
> an isolated partition, its invalidation should have properly updated
> isolated_cpus before and no action will be needed.
>
> Fix that by calling isolated_cpus_update() in this invalidation case
> to update isolated_cpus. A test case in test_cpuset_prs.sh is modified
> to test that.
>
> Fixes: 11e5f407b64a ("cgroup/cpuset: Keep track of CPUs in isolated
> partitions")
> Signed-off-by: Waiman Long <[email protected]>
> ---
> kernel/cgroup/cpuset.c | 19 ++++++++++++++-----
> .../selftests/cgroup/test_cpuset_prs.sh | 4 ++--
> 2 files changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
> index 0ebba2d646c3..6b5c870e5607 100644
> --- a/kernel/cgroup/cpuset.c
> +++ b/kernel/cgroup/cpuset.c
> @@ -2229,7 +2229,9 @@ static void update_cpumasks_hier(struct cpuset *cs,
> struct tmpmasks *tmp,
> * cpuset if the parent's effective_cpus changes.
> */
> if ((cp != cs) && old_prs) {
> - switch (parent->partition_root_state) {
> + int parent_prs = parent->partition_root_state;
> +
> + switch (parent_prs) {
> case PRS_ROOT:
> case PRS_ISOLATED:
> update_parent = true;
> @@ -2238,11 +2240,18 @@ static void update_cpumasks_hier(struct cpuset *cs,
> struct tmpmasks *tmp,
> default:
> /*
> * When parent is not a partition root or is
> - * invalid, child partition roots become
> - * invalid too.
> + * invalid, child partition roots become invalid
> + * too. For an isolated partition with root
> + * partition parent, isolated_cpus_updated()
> + * is called to update isolated_cpus.
> */
> - if (is_partition_valid(cp))
> - new_prs = -cp->partition_root_state;
> + if (is_partition_valid(cp)) {
> + new_prs = -old_prs;
> + if ((old_prs == PRS_ISOLATED) &&
> + (parent_prs == -PRS_ROOT))
> + isolated_cpus_update(old_prs,
> new_prs,
> +
> cp->effective_xcpus);
> + }
I tested switching a parent partition from root to member and found that
CPUs can remain listed in cpuset.cpus.isolated. CPUs 0-15 are online, with
nohz_full=2-15 and no isolcpus:
# cd /sys/fs/cgroup
# echo +cpuset > cgroup.subtree_control
# mkdir A
# echo 1-2 > A/cpuset.cpus
# echo root > A/cpuset.cpus.partition
# echo +cpuset > A/cgroup.subtree_control
# mkdir A/C
# echo 2 > A/C/cpuset.cpus
# echo isolated > A/C/cpuset.cpus.partition
# cat cpuset.cpus.isolated
2
# echo member > A/cpuset.cpus.partition
# cat A/C/cpuset.cpus.partition
isolated invalid (Parent is not a partition root)
# cat cpuset.cpus.isolated
2
A is now a member and C is invalid, so cpuset.cpus.isolated should be
empty here, but CPU 2 remains.
Thanks,
Guopeng> WRITE_ONCE(cp->prs_err,
> is_partition_invalid(parent)
> ? PERR_INVPARENT : PERR_NOTPART);
> diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> index 7efd5e645767..874a8a161236 100755
> --- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> +++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> @@ -292,9 +292,9 @@ TEST_MATRIX=(
>
> A1:P0|A2:P2|A3:P1 2-4|2-3"
> " C0-4 C1-4 C2-4 . X2-4 X2-4:P2 X3-4:P1 . 0
> A1:0-1|A2:2|A3:3-4 \
>
> A1:P0|A2:P2|A3:P1 2"
> - " C0-4:X2-4 C1-4:X2-4:P2 C2-4:X4:P1 \
> + " C0-4:X2-4 C1-4:X2-4:P1 C2-4:X4:P2 \
> . . X5 . . 0
> A1:0-4|A2:1-4|A3:2-4 \
> -
> A1:P0|A2:P-2|A3:P-1 ."
> +
> A1:P0|A2:P-1|A3:P-2 ."
> " C0-4:X2-4 C1-4:X2-4:P2 C2-4:X4:P1 \
> . . . X1 . 0
> A1:0-1|A2:2-4|A3:2-4 \
>
> A1:P0|A2:P2|A3:P-1 2-4"