[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251225123058.231765-16-chenridong@huaweicloud.com>
Date: Thu, 25 Dec 2025 12:30:52 +0000
From: Chen Ridong <chenridong@...weicloud.com>
To: longman@...hat.com,
tj@...nel.org,
hannes@...xchg.org,
mkoutny@...e.com
Cc: cgroups@...r.kernel.org,
linux-kernel@...r.kernel.org,
lujialin4@...wei.com,
chenridong@...weicloud.com
Subject: [PATCH RESEND -next 15/21] cpuset: simplify partition update logic for hotplug tasks
From: Chen Ridong <chenridong@...wei.com>
Simplify the partition update logic in cpuset_hotplug_update_tasks() by
calling the unified local_partition_update() interface.
For local partitions, the previous patch introduced local_partition_update
which handles both validation state transitions:
- Invalidates local partitions that fail validation checks
- Transitions invalid partitions to valid state when no errors are detected
This eliminates the need for separate transition logic
in cpuset_hotplug_update_tasks(), which can now simply call
local_partition_update() to handle all local partition changes.
For remote partitions, the logic is adjusted to always proceed to
update_tasks regardless of whether the partition was disabled, as the
original skip condition was not valid for remote partitions. This change
maintains existing functionality while simplifying the code path.
The partition_cmd emum type can now be safely removed as it is no longer
referenced by any code paths after the partition update logic
simplification.
Signed-off-by: Chen Ridong <chenridong@...wei.com>
---
kernel/cgroup/cpuset.c | 75 ++++++++++++++----------------------------
1 file changed, 25 insertions(+), 50 deletions(-)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index a1df78a75575..99413472a0fb 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1072,17 +1072,6 @@ static void compute_effective_cpumask(struct cpumask *new_cpus,
cpumask_and(new_cpus, cs->cpus_allowed, parent->effective_cpus);
}
-/*
- * Commands for update_parent_effective_cpumask
- */
-enum partition_cmd {
- partcmd_enable, /* Enable partition root */
- partcmd_enablei, /* Enable isolated partition root */
- partcmd_disable, /* Disable partition root */
- partcmd_update, /* Update parent's effective_cpus */
- partcmd_invalidate, /* Make partition invalid */
-};
-
static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs,
struct tmpmasks *tmp);
@@ -3701,8 +3690,6 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
static nodemask_t new_mems;
bool cpus_updated;
bool mems_updated;
- bool remote;
- int partcmd = -1;
struct cpuset *parent;
retry:
wait_event(cpuset_attach_wq, cs->attach_in_progress == 0);
@@ -3729,50 +3716,38 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
* Compute effective_cpus for valid partition root, may invalidate
* child partition roots if necessary.
*/
- remote = is_remote_partition(cs);
- if (remote || (is_partition_valid(cs) && is_partition_valid(parent)))
+ if (is_remote_partition(cs)) {
compute_partition_effective_cpumask(cs, &new_cpus);
-
- 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);
- remote = false;
+ if (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);
+ }
+ goto update_tasks;
}
/*
- * Force the partition to become invalid if either one of
- * the following conditions hold:
- * 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) ||
- cpumask_empty(subpartitions_cpus))) {
- partcmd = partcmd_invalidate;
- local_partition_disable(cs, cs->prs_err, tmp);
- }
- /*
- * On the other hand, an invalid partition root may be transitioned
- * back to a regular one with a non-empty user xcpus.
+ * The subpartitions_cpus may be cleared if no CPUs remain available for
+ * the top_cpuset. In this case, disable the local partition directly.
+ * Otherwise, local_partition_update will handle the automatic transition
+ * between valid and invalid partition states.
*/
- else if (is_partition_valid(parent) && is_partition_invalid(cs) &&
- !cpumask_empty(user_xcpus(cs))) {
- partcmd = partcmd_update;
+ if (is_local_partition(cs) && cpumask_empty(subpartitions_cpus))
+ local_partition_disable(cs, PERR_HOTPLUG, tmp);
+ else
local_partition_update(cs, tmp);
- }
- if (partcmd >= 0) {
- if ((partcmd == partcmd_invalidate) || is_partition_valid(cs)) {
- compute_partition_effective_cpumask(cs, &new_cpus);
- cpuset_force_rebuild();
- }
- }
+ /*
+ * Recompute effective CPU mask after partition state update:
+ * - For valid partitions: calculate partition-specific effective CPUs
+ * - For invalid partitions: compute member effective CPU mask
+ */
+ if (is_partition_valid(cs))
+ compute_partition_effective_cpumask(cs, &new_cpus);
+ else
+ compute_effective_cpumask(&new_cpus, cs, parent);
update_tasks:
cpus_updated = !cpumask_equal(&new_cpus, cs->effective_cpus);
--
2.34.1
Powered by blists - more mailing lists