From: Guopeng Zhang <guopeng.zhang@linux.dev>
To: longman@redhat.com, tj@kernel.org, ridong.chen@linux.dev
Cc: guopeng.zhang@linux.dev, hannes@cmpxchg.org, mkoutny@suse.com,
shuah@kernel.org, cgroups@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
Guopeng Zhang <zhangguopeng@kylinos.cn>
Subject: [PATCH v2 2/3] cgroup/cpuset: Keep the top sched domain non-empty on CPU hotplug
Date: Thu, 5 Nov 2026 21:03:43 +0800 [thread overview]
Message-ID: <20261105130344.664336-3-guopeng.zhang@linux.dev> (raw)
In-Reply-To: <20261105130344.664336-1-guopeng.zhang@linux.dev>
From: Guopeng Zhang <zhangguopeng@kylinos.cn>
Configuration updates must leave an active boot domain housekeeping CPU
in the top cpuset, but CPU hotplug can still empty its scheduling domain.
For a local partition with child partitions, cpuset_hotplug_update_tasks()
passes the partition's own effective CPUs to tasks_nocpu_error(). The
embedded top_cpuset_sd_nocpu() check credits the old exclusive CPUs not
in that mask as CPUs being returned to the top cpuset. Those CPUs may
still belong to child partitions, so no such return takes place.
For example, with isolcpus=domain,10-31 on a 32-CPU system:
echo 0,2-9 > A/cpuset.cpus
echo root > A/cpuset.cpus.partition
echo 5-9 > A/B/cpuset.cpus
echo root > A/B/cpuset.cpus.partition
echo 0 > /sys/devices/system/cpu/cpu1/online
Oops: general protection fault
RIP: 0010:build_perf_domains+...
Remote partition hotplug checks also miss the empty top scheduling
domain because they only examine the remote partition's own CPUs.
Check the local partition's full exclusive mask without crediting any
returned CPUs. For remote partitions, check the top scheduling domain
with all partition grants still excluded. Invalidate a partition through
its existing path to return its CPUs. Once an active boot domain
housekeeping CPU is returned, subsequent partitions no longer fail this
check.
Add hotplug test cases to test_cpuset_prs.sh to verify that the top
cpuset sched domain stays non-empty when the last housekeeping CPU
goes away.
Fixes: 9b496a8bbed9 ("cgroup/cpuset: Prevent leakage of isolated CPUs into sched domains")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
---
kernel/cgroup/cpuset.c | 4 ++++
tools/testing/selftests/cgroup/test_cpuset_prs.sh | 8 ++++++++
2 files changed, 12 insertions(+)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index c405719ccd12..fc5454c2740f 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -4053,6 +4053,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
goto update_tasks;
if (is_remote_partition(cs) && (cpumask_empty(subpartitions_cpus) ||
+ top_cpuset_sd_nocpu(subpartitions_cpus, NULL) ||
(cpumask_empty(&new_cpus) &&
partition_is_populated(cs, NULL)))) {
WRITE_ONCE(cs->prs_err, PERR_HOTPLUG);
@@ -4067,9 +4068,12 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
* 2) parent is invalid or doesn't grant any cpus to child
* partitions.
* 3) subpartitions_cpus is empty.
+ * 4) top_cpuset has no active boot domain housekeeping CPU left.
*/
if (is_local_partition(cs) &&
(!is_partition_valid(parent) ||
+ (parent == &top_cpuset &&
+ top_cpuset_sd_nocpu(cs->effective_xcpus, NULL)) ||
tasks_nocpu_error(parent, cs, &new_cpus) ||
cpumask_empty(subpartitions_cpus)))
partcmd = partcmd_invalidate;
diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
index e813ea9959f4..f03fffeab034 100755
--- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
+++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
@@ -646,6 +646,14 @@ ISOLCPUS_DOMAIN_TEST_MATRIX=(
# An invalid partition can recover once it leaves a top-level HK CPU.
" C0-9:P1 . . . C0-8 . . . 0 A1:0-8 A1:P1 ."
+
+ # Offlining CPU 1 leaves only boot-isolated CPUs in the top cpuset.
+ # A local root must not count its child's CPUs as already returned.
+ # In 1|, offline CPU 1 has no sched domain but is not cpuset-isolated.
+ " C0,2-9:P1 C5-9:P1 . . O1=0 . . . 0 A1:0,2-9|A2:5-9 A1:P-1|A2:P-1 1|"
+
+ # A remote root must return CPUs when the top domain loses its last HK CPU.
+ " X0,2-9 CX0,2-9:P1 . . O1=0 . . . 0 A2:0,2-9 A2:P-1 1|"
)
# Test matrix to be run when boot time nohz_full CPUs cover all CPUs except CPUs 0-7
--
2.43.0
next prev parent reply other threads:[~2026-11-05 13:04 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 13:03 [PATCH v2 0/3] cgroup/cpuset: Keep the top scheduling domain populated Guopeng Zhang
2026-11-05 13:03 ` [PATCH v2 1/3] cgroup/cpuset: Reject updates that empty the top sched domain Guopeng Zhang
2026-11-05 13:03 ` Guopeng Zhang [this message]
2026-11-05 13:03 ` [PATCH v2 3/3] cgroup/cpuset: Release isolated CPUs when the parent is invalid Guopeng Zhang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261105130344.664336-3-guopeng.zhang@linux.dev \
--to=guopeng.zhang@linux.dev \
--cc=cgroups@vger.kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mkoutny@suse.com \
--cc=ridong.chen@linux.dev \
--cc=shuah@kernel.org \
--cc=tj@kernel.org \
--cc=zhangguopeng@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®