[RFC PATCH -v4 06/22] cpuset: introduce partition_update()

From: Ridong Chen

Date: Sun Nov 01 2026 - 06:43:22 EST


From: Chen Ridong <chenridong@xxxxxxxxxx>

Introduce partition_update() to centralize updates to key cpuset structures
during a partition update, including:
1. effective_xcpus
2. exclusive_cpus

Key operations performed:
1. Adding and removing exclusive CPUs via partition_xcpus_add()/del()
2. Synchronizing the effective exclusive CPUs mask
3. Updating the exclusive CPUs mask when modification is required
4. Triggering scheduler domain rebuilds

For a local partition, the CPUs to be added or deleted are restricted to
those in the parent's effective_xcpus, as the parent may have shrunk.
The function returns early if nothing is to be changed.

The partition root state is unchanged by this function, so no partition
change notification is sent.

Signed-off-by: Chen Ridong <chenridong@xxxxxxxxxx>
Signed-off-by: Ridong Chen <chenridong@xxxxxxxxxx>
---
kernel/cgroup/cpuset.c | 51 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)

diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index c0d6dd7297f1..23ae548c3994 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1806,6 +1806,57 @@ static void partition_disable(struct cpuset *cs, struct cpuset *parent,
notify_partition_change(cs, old_prs);
}

+/**
+ * partition_update - Update an existing partition configuration
+ * @cs: The cpuset to update
+ * @prs: Partition root state (must be positive)
+ * @xcpus: New exclusive CPUs mask for the partition (NULL to keep current)
+ * @excpus: New effective exclusive CPUs mask
+ * @tmp: Temporary masks
+ *
+ * Updates partition-related fields. The tmp->addmask is the CPU mask that
+ * will be added to the subpartitions_cpus and removed from parent's
+ * effective_cpus, and the tmp->delmask vice versa.
+ */
+static void partition_update(struct cpuset *cs, int prs, struct cpumask *xcpus,
+ struct cpumask *excpus, struct tmpmasks *tmp)
+{
+ struct cpuset *parent;
+
+ lockdep_assert_cpuset_lock_held();
+ WARN_ON_ONCE(!cpuset_v2());
+ WARN_ON_ONCE(prs <= 0);
+
+ parent = is_remote_partition(cs) ? NULL : parent_cs(cs);
+
+ /*
+ * Only CPUs owned by the parent can be taken from or given back to
+ * it, the parent may have shrunk. A remote partition gets its CPUs
+ * from top_cpuset which owns all the CPUs.
+ */
+ if (parent) {
+ cpumask_and(tmp->addmask, tmp->addmask, parent->effective_xcpus);
+ cpumask_and(tmp->delmask, tmp->delmask, parent->effective_xcpus);
+ }
+ if (cpumask_empty(tmp->addmask) &&
+ cpumask_empty(tmp->delmask) &&
+ cpumask_equal(cs->effective_xcpus, excpus))
+ return;
+
+ spin_lock_irq(&callback_lock);
+ partition_xcpus_add(prs, parent, tmp->addmask);
+ partition_xcpus_del(prs, parent, tmp->delmask);
+ /*
+ * Need to update effective_xcpus and exclusive_cpus now as
+ * update_sibling_cpumasks() below may iterate back to the same cs.
+ */
+ cpumask_copy(cs->effective_xcpus, excpus);
+ if (xcpus)
+ cpumask_copy(cs->exclusive_cpus, xcpus);
+ spin_unlock_irq(&callback_lock);
+ cpuset_force_rebuild();
+}
+
/*
* remote_partition_enable - Enable current cpuset as a remote partition root
* @cs: the cpuset to update
--
2.34.1