]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cpuset: fix warning when disabling remote partition
authorChen Ridong <chenridong@huawei.com>
Thu, 18 Dec 2025 01:59:50 +0000 (01:59 +0000)
committerTejun Heo <tj@kernel.org>
Thu, 18 Dec 2025 16:38:54 +0000 (06:38 -1000)
A warning was triggered as follows:

WARNING: kernel/cgroup/cpuset.c:1651 at remote_partition_disable+0xf7/0x110
RIP: 0010:remote_partition_disable+0xf7/0x110
RSP: 0018:ffffc90001947d88 EFLAGS: 00000206
RAX: 0000000000007fff RBX: ffff888103b6e000 RCX: 0000000000006f40
RDX: 0000000000006f00 RSI: ffffc90001947da8 RDI: ffff888103b6e000
RBP: ffff888103b6e000 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000001 R11: ffff88810b2e2728 R12: ffffc90001947da8
R13: 0000000000000000 R14: ffffc90001947da8 R15: ffff8881081f1c00
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f55c8bbe0b2 CR3: 000000010b14c000 CR4: 00000000000006f0
Call Trace:
 <TASK>
 update_prstate+0x2d3/0x580
 cpuset_partition_write+0x94/0xf0
 kernfs_fop_write_iter+0x147/0x200
 vfs_write+0x35d/0x500
 ksys_write+0x66/0xe0
 do_syscall_64+0x6b/0x390
 entry_SYSCALL_64_after_hwframe+0x4b/0x53
RIP: 0033:0x7f55c8cd4887

Reproduction steps (on a 16-CPU machine):

        # cd /sys/fs/cgroup/
        # mkdir A1
        # echo +cpuset > A1/cgroup.subtree_control
        # echo "0-14" > A1/cpuset.cpus.exclusive
        # mkdir A1/A2
        # echo "0-14" > A1/A2/cpuset.cpus.exclusive
        # echo "root" > A1/A2/cpuset.cpus.partition
        # echo 0 > /sys/devices/system/cpu/cpu15/online
        # echo member > A1/A2/cpuset.cpus.partition

When CPU 15 is offlined, subpartitions_cpus gets cleared because no CPUs
remain available for the top_cpuset, forcing partitions to share CPUs with
the top_cpuset. In this scenario, disabling the remote partition triggers
a warning stating that effective_xcpus is not a subset of
subpartitions_cpus. Partitions should be invalidated in this case to
inform users that the partition is now invalid(cpus are shared with
top_cpuset).

To fix this issue:
1. Only emit the warning only if subpartitions_cpus is not empty and the
   effective_xcpus is not a subset of subpartitions_cpus.
2. During the CPU hotplug process, invalidate partitions if
   subpartitions_cpus is empty.

Fixes: f62a5d39368e ("cgroup/cpuset: Remove remote_partition_check() & make update_cpumasks_hier() handle remote partition")
Signed-off-by: Chen Ridong <chenridong@huawei.com>
Reviewed-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/cgroup/cpuset.c

index 6e6eb09b8db6830c7157ac5a931ff82012d91e22..3e8cc34d8d5023c79383d4d9db72d2599fb8f743 100644 (file)
@@ -1668,7 +1668,14 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
 static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp)
 {
        WARN_ON_ONCE(!is_remote_partition(cs));
-       WARN_ON_ONCE(!cpumask_subset(cs->effective_xcpus, subpartitions_cpus));
+       /*
+        * When a CPU is offlined, top_cpuset may end up with no available CPUs,
+        * which should clear subpartitions_cpus. We should not emit a warning for this
+        * scenario: the hierarchy is updated from top to bottom, so subpartitions_cpus
+        * may already be cleared when disabling the partition.
+        */
+       WARN_ON_ONCE(!cpumask_subset(cs->effective_xcpus, subpartitions_cpus) &&
+                    !cpumask_empty(subpartitions_cpus));
 
        spin_lock_irq(&callback_lock);
        cs->remote_partition = false;
@@ -3976,8 +3983,9 @@ retry:
        if (remote || (is_partition_valid(cs) && is_partition_valid(parent)))
                compute_partition_effective_cpumask(cs, &new_cpus);
 
-       if (remote && cpumask_empty(&new_cpus) &&
-           partition_is_populated(cs, NULL)) {
+       if (remote && (cpumask_empty(subpartitions_cpus) ||
+                       (cpumask_empty(&new_cpus) &&
+                        partition_is_populated(cs, NULL)))) {
                cs->prs_err = PERR_HOTPLUG;
                remote_partition_disable(cs, tmp);
                compute_effective_cpumask(&new_cpus, cs, parent);
@@ -3990,9 +3998,12 @@ retry:
         * 1) empty effective cpus but not valid empty partition.
         * 2) parent is invalid or doesn't grant any cpus to child
         *    partitions.
+        * 3) subpartitions_cpus is empty.
         */
-       if (is_local_partition(cs) && (!is_partition_valid(parent) ||
-                               tasks_nocpu_error(parent, cs, &new_cpus)))
+       if (is_local_partition(cs) &&
+           (!is_partition_valid(parent) ||
+            tasks_nocpu_error(parent, cs, &new_cpus) ||
+            cpumask_empty(subpartitions_cpus)))
                partcmd = partcmd_invalidate;
        /*
         * On the other hand, an invalid partition root may be transitioned