[PATCH 21/23] cgroup/cpuset: Limit the side effect of using CPU hotplug on isolated partition

Waiman Long
2026-04-21T03:07:38Z

CPU hotplug is used to facilitate the modification of the
HK_TYPE_KERNEL_NOISE and HK_TYPE_MANAGED_IRQ cpumasks. However, tearing
down and bringing up CPUs can impact the cpuset partition states
as well. For instance, tearing down the last CPU of a partition can
invalidate the partition with active tasks which will not happen if
CPU hotplug isn't used.

A workaround of this issue is disable the invalidation by pretending that
the partition has no task, and making the tasks within the partition
to the effective CPUs of its parent for a short while during the short
transition process where the CPUs will be teared down and the brought
up again.

Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/cgroup/cpuset.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index a927b9cd4f71..5f6b4e67748f 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -434,6 +434,13 @@ static inline bool partition_is_populated(struct cpuset *cs,
struct cpuset *cp;
struct cgroup_subsys_state *pos_css;

+ /*
+ * Hack: In cpuhp_offline_cb_mode, pretend all partitions are empty
+ * to prevent unnecessary partition invalidation.
+ */
+ if (cpuhp_offline_cb_mode)
+ return false;
+
/*
* We cannot call cs_is_populated(cs) directly, as
* nr_populated_domain_children may include populated
@@ -3881,6 +3888,17 @@ hotplug_update_tasks(struct cpuset *cs,
cs->effective_mems = *new_mems;
spin_unlock_irq(&callback_lock);

+ /*
+ * When cpuhp_offline_cb_mode is active, valid isolated partition
+ * with tasks may have no online CPUs available for a short while.
+ * In that case, we fall back to parent's effective CPUs temporarily
+ * which will be reset back to their rightful value once the affected
+ * CPUs are online again.
+ */
+ if (cpuhp_offline_cb_mode && cpumask_empty(new_cpus) &&
+ (cs->partition_root_state == PRS_ISOLATED))
+ cpumask_copy(new_cpus, parent_cs(cs)->effective_cpus);
+
if (cpus_updated)
cpuset_update_tasks_cpumask(cs, new_cpus);
if (mems_updated)
--
2.53.0