On 10/15/26 11:30 PM, Guopeng Zhang wrote:

在 2026/10/14 22:05, Waiman Long 写道:
Although it is not typical for real users to create a complicated nested
partition hierarchy, it is currently allowed to create nested root and
isolated partitions. In addition, disabling or invalidating a partition
should always be allowed especially when the cpuset is being deleted.

With a nested root and isolated partition hierarchy, it is possible
that all active housekeeping CPUs can be exhausted when disabling or
invalidating a root partition and returning its CPUs to the isolated
parent.

One way to avoid this problem is to disallow the creation of a root
partition under an isolated parent. It is indeed a new limitation imposed
on the existing cpuset partition functionality. However an isolated
partition is usually a left node where scheduling and some other kernel
noises are disabled. It doesn't make much sense to create a child root
partition under an isolated parent and remove some CPUs from the set
of isolated CPUs again. Creation of a child isolated partition under a
root or isolated parent is still allowed.

The cgroup-v2 documentation is also updated to reflect this new
limitation. New test cases are added to test_cpuset_prs.sh to verify
this new behavior. Some existing test cases are also updated accordingly.

Signed-off-by: Waiman Long <[email protected]>
---
  Documentation/admin-guide/cgroup-v2.rst           |  4 +++-
  kernel/cgroup/cpuset-internal.h                   |  1 +
  kernel/cgroup/cpuset.c                            | 13 +++++++++++++
  tools/testing/selftests/cgroup/test_cpuset_prs.sh | 14 ++++++++------
  4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/Documentation/admin-guide/cgroup-v2.rst 
b/Documentation/admin-guide/cgroup-v2.rst
index bd8c80f3bbc9..2c445829e24d 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2767,7 +2767,9 @@ Cpuset Interface Files
        be retained, but behaves more like a "member".
All possible state transitions among "member", "root" and
-       "isolated" are allowed.
+       "isolated" are allowed with the exception that a local child
+       "root" partition is not allowed to be created under an "isolated"
+       parent partition.
On read, the "cpuset.cpus.partition" file can show the following
        values.
diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
index 5da9c91295b0..2e44dc8634dc 100644
--- a/kernel/cgroup/cpuset-internal.h
+++ b/kernel/cgroup/cpuset-internal.h
@@ -35,6 +35,7 @@ enum prs_errcode {
        PERR_HKEEPING,
        PERR_ACCESS,
        PERR_REMOTE,
+       PERR_ISOPARENT,
  };
/* bits in struct cpuset flags field */
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 40c004386af0..681701ba46e1 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -60,6 +60,7 @@ static const char * const perr_strings[] = {
        [PERR_HKEEPING]  = "partition config conflicts with housekeeping setup",
        [PERR_ACCESS]    = "Enable partition not permitted",
        [PERR_REMOTE]    = "Have remote partition underneath",
+       [PERR_ISOPARENT] = "Root partition is not allowed with isolated parent",
  };
/*
@@ -2865,6 +2866,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
        int err = PERR_NONE, old_prs = cs->partition_root_state;
        struct cpuset *parent = parent_cs(cs);
        struct tmpmasks tmpmask;
+       int parent_prs = parent->partition_root_state;
        bool isolcpus_updated = false;
        bool disable_partition = false;
@@ -2910,6 +2912,14 @@ static int update_prstate(struct cpuset *cs, int new_prs)
                        enum partition_cmd cmd = (new_prs == PRS_ROOT)
                                               ? partcmd_enable : 
partcmd_enablei;
+ /*
+                        * It is not allowed to create a root partition under
+                        * an isolated parent partition.
+                        */
+                       if ((new_prs == PRS_ROOT) && (parent_prs == 
PRS_ISOLATED)) {
+                               err = PERR_ISOPARENT;
+                               goto out;
+                       }
I tested the following case. Writing root initially leaves C invalid, but
updating its cpuset.cpus makes it valid again.

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 isolated > A/cpuset.cpus.partition
     # echo +cpuset > A/cgroup.subtree_control
     # mkdir A/C
     # echo 1 > A/C/cpuset.cpus
     # echo root > A/C/cpuset.cpus.partition
     # cat A/C/cpuset.cpus.partition
     root invalid (Root partition is not allowed with isolated parent)
     # echo 1-2 > A/C/cpuset.cpus
     # cat A/C/cpuset.cpus.partition
     root

C becomes a valid root partition.

Thank for finding this bug. Yes, the patch is missing check in some places. Will fix in the next version.

Cheers,
Longman


Reply via email to