Re: [PATCH-next v3 1/9] cgroup/cpuset: Fix a missing isolated_cpus update in update_cpumasks_hier()
From: Waiman Long
Date: Mon Oct 19 2026 - 13:44:05 EST
On 10/15/26 9:02 AM, Guopeng Zhang wrote:
在 2026/10/14 22:05, Waiman Long 写道:
It is found that when a local isolated partition is being invalidatedI tested switching a parent partition from root to member and found that
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 <longman@xxxxxxxxxx>
---
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);
+ }
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.
Yes, this patch isn't quite correct and can't catch some corner cases. I have a new version that should work much better and I can't reproduce your test case with the new patch. I will send out a v4 soon.
Cheers,
Longman
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"