From: Guopeng Zhang <guopeng.zhang@linux.dev>
To: "Waiman Long" <longman@redhat.com>,
"Ridong Chen" <ridong.chen@linux.dev>,
"Tejun Heo" <tj@kernel.org>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Michal Koutný" <mkoutny@suse.com>,
"Shuah Khan" <shuah@kernel.org>
Cc: cgroups@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: Re: [PATCH-next v3 10/11] cgroup/cpuset: Relocate compute_*effective_cpumask() and compute_effective_nodemask()
Date: Mon, 26 Oct 2026 17:08:18 +0800 [thread overview]
Message-ID: <2eb44d83-b5ff-4a6e-94ae-956993da48ea@linux.dev> (raw)
In-Reply-To: <20261025214449.310715-11-longman@redhat.com>
在 2026/10/26 05:44, Waiman Long 写道:
> Relocate compute_partition_effective_cpumask(),
> compute_effective_cpumask(), and compute_effective_nodemask() together so
> that compute_effective_cpumask() and compute_partition_effective_cpumask()
> can be further integrated together. There is no functional change.
>
> Signed-off-by: Waiman Long <longman@redhat.com>
> ---
> kernel/cgroup/cpuset.c | 212 ++++++++++++++++++++---------------------
> 1 file changed, 106 insertions(+), 106 deletions(-)
>
> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
> index 3daab2381f04..f37d929616a6 100644
> --- a/kernel/cgroup/cpuset.c
> +++ b/kernel/cgroup/cpuset.c
> @@ -1135,43 +1135,6 @@ void cpuset_update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus)
> css_task_iter_end(&it);
> }
>
> -/**
> - * compute_effective_cpumask - Compute the effective cpumask of the cpuset
> - * @new_cpus: the temp variable for the new effective_cpus mask
> - * @cs: the cpuset the need to recompute the new effective_cpus mask
> - * @parent: the parent cpuset
> - *
> - * For v2, the parent's effective_cpus is inherited if cpumask is empty.
> - * The result is valid only if the given cpuset isn't a partition root.
> - */
> -static void compute_effective_cpumask(struct cpumask *new_cpus,
> - struct cpuset *cs, struct cpuset *parent)
> -{
> - bool has_cpus;
> -
> - has_cpus = cpumask_and(new_cpus, cs->cpus_allowed, parent->effective_cpus);
> - if (!has_cpus && is_in_v2_mode())
> - cpumask_copy(new_cpus, parent->effective_cpus);
> -}
> -
> -/**
> - * compute_effective_nodemask - Compute the effective nodemask of the cpuset
> - * @new_mems: the temp variable for the new effective_mems mask
> - * @cs: the cpuset the need to recompute the new effective_mems mask
> - * @parent: the parent cpuset
> - *
> - * For v2, the parent's effective_mems is inherited if nodemask is empty.
> - */
> -static void compute_effective_nodemask(nodemask_t *new_mems,
> - struct cpuset *cs, struct cpuset *parent)
> -{
> - bool has_mems;
> -
> - has_mems = nodes_and(*new_mems, cs->mems_allowed, parent->effective_mems);
> - if (!has_mems && is_in_v2_mode())
> - nodes_copy(*new_mems, parent->effective_mems);
> -}
> -
> /*
> * Commands for update_parent_effective_cpumask
> */
> @@ -1622,6 +1585,112 @@ static int compute_trialcs_excpus(struct cpuset *trialcs, struct cpuset *cs)
> return rm_siblings_excl_cpus(parent, cs, excpus);
> }
>
> +/**
> + * compute_partition_effective_cpumask - compute effective_cpus for partition
> + * @cs: partition root cpuset
> + * @new_ecpus: previously computed effective_cpus to be updated
> + *
> + * Compute the effective_cpus of a partition root by scanning effective_xcpus
> + * of child partition roots and excluding their effective_xcpus.
> + *
> + * This has the side effect of invalidating valid child partition roots,
> + * if necessary. Since it is called from either cpuset_hotplug_update_tasks()
> + * or update_cpumasks_hier() where parent and children are modified
> + * successively, we don't need to call update_parent_effective_cpumask()
> + * and the child's effective_cpus will be updated in later iterations.
> + */
> +static void compute_partition_effective_cpumask(struct cpuset *cs,
> + struct cpumask *new_ecpus)
> +{
> + struct cgroup_subsys_state *css;
> + struct cpuset *child;
> + bool populated = partition_is_populated(cs, NULL);
> +
> + WARN_ON_ONCE(!is_partition_valid(cs));
> +
> + /*
> + * Check child partition roots to see if they should be invalidated
> + * when all the effective_cpus will be used up and cs is populated.
> + * It is better to sacrifice a child partition root than invalidating
> + * the whole subtree.
> + *
> + * Return early if the effective_cpus is already empty.
> + */
> + compute_excpus(cs, new_ecpus);
> + if (!cpumask_and(new_ecpus, new_ecpus, cpu_active_mask))
> + return;
> +
> + rcu_read_lock();
> + cpuset_for_each_child(child, css, cs) {
> + if (!is_partition_valid(child))
> + continue;
> +
> + /*
> + * There shouldn't be a remote partition underneath another
> + * partition root.
> + */
> + WARN_ON_ONCE(is_remote_partition(child));
> + if (populated && cpumask_subset(new_ecpus, child->effective_xcpus)) {
> + int old_prs = child->partition_root_state;
> + int parent_prs = cs->partition_root_state;
> +
> + /*
> + * Invalidate child partition and update isolated_cpus
> + * if necessary.
> + */
> + spin_lock_irq(&callback_lock);
> + WRITE_ONCE(child->prs_err, PERR_NOCPUS);
> + if ((old_prs == PRS_ISOLATED) && (parent_prs == PRS_ROOT))
> + isolated_cpus_update(PRS_ISOLATED, PRS_ROOT,
> + child->effective_xcpus);
> + child->partition_root_state = -old_prs;
> + spin_unlock_irq(&callback_lock);
> + notify_partition_change(child, old_prs);
> + continue;
> + }
> + cpumask_andnot(new_ecpus, new_ecpus,
> + child->effective_xcpus);
> + }
> + rcu_read_unlock();
> +}
> +
> +/**
> + * compute_effective_cpumask - Compute the effective cpumask of the cpuset
> + * @new_cpus: the temp variable for the new effective_cpus mask
> + * @cs: the cpuset the need to recompute the new effective_cpus mask
> + * @parent: the parent cpuset
> + *
> + * For v2, the parent's effective_cpus is inherited if cpumask is empty.
> + * The result is valid only if the given cpuset isn't a partition root.
> + */
> +static void compute_effective_cpumask(struct cpumask *new_cpus,
> + struct cpuset *cs, struct cpuset *parent)
> +{
> + bool has_cpus;
> +
> + has_cpus = cpumask_and(new_cpus, cs->cpus_allowed, parent->effective_cpus);
> + if (!has_cpus && is_in_v2_mode())
> + cpumask_copy(new_cpus, parent->effective_cpus);
> +}
> +
> +/**
> + * compute_effective_nodemask - Compute the effective nodemask of the cpuset
> + * @new_mems: the temp variable for the new effective_mems mask
> + * @cs: the cpuset the need to recompute the new effective_mems mask
> + * @parent: the parent cpuset
> + *
> + * For v2, the parent's effective_mems is inherited if nodemask is empty.
> + */
> +static void compute_effective_nodemask(nodemask_t *new_mems,
> + struct cpuset *cs, struct cpuset *parent)
> +{
> + bool has_mems;
> +
> + has_mems = nodes_and(*new_mems, cs->mems_allowed, parent->effective_mems);
> + if (!has_mems && is_in_v2_mode())
> + nodes_copy(*new_mems, parent->effective_mems);
> +}
> +
> /*
> * remote_partition_enable - Enable current cpuset as a remote partition root
> * @cs: the cpuset to update
> @@ -2145,75 +2214,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
> return 0;
> }
>
> -/**
> - * compute_partition_effective_cpumask - compute effective_cpus for partition
> - * @cs: partition root cpuset
> - * @new_ecpus: previously computed effective_cpus to be updated
> - *
> - * Compute the effective_cpus of a partition root by scanning effective_xcpus
> - * of child partition roots and excluding their effective_xcpus.
> - *
> - * This has the side effect of invalidating valid child partition roots,
> - * if necessary. Since it is called from either cpuset_hotplug_update_tasks()
> - * or update_cpumasks_hier() where parent and children are modified
> - * successively, we don't need to call update_parent_effective_cpumask()
> - * and the child's effective_cpus will be updated in later iterations.
> - */
> -static void compute_partition_effective_cpumask(struct cpuset *cs,
> - struct cpumask *new_ecpus)
> -{
> - struct cgroup_subsys_state *css;
> - struct cpuset *child;
> - bool populated = partition_is_populated(cs, NULL);
> -
> - WARN_ON_ONCE(!is_partition_valid(cs));
> -
> - /*
> - * Check child partition roots to see if they should be invalidated
> - * when all the effective_cpus will be used up and cs is populated.
> - * It is better to sacrifice a child partition root than invalidating
> - * the whole subtree.
> - *
> - * Return early if the effective_cpus is already empty.
> - */
> - compute_excpus(cs, new_ecpus);
> - if (!cpumask_and(new_ecpus, new_ecpus, cpu_active_mask))
> - return;
> -
> - rcu_read_lock();
> - cpuset_for_each_child(child, css, cs) {
> - if (!is_partition_valid(child))
> - continue;
> -
> - /*
> - * There shouldn't be a remote partition underneath another
> - * partition root.
> - */
> - WARN_ON_ONCE(is_remote_partition(child));
> - if (populated && cpumask_subset(new_ecpus, child->effective_xcpus)) {
> - int old_prs = child->partition_root_state;
> - int parent_prs = cs->partition_root_state;
> -
> - /*
> - * Invalidate child partition and update isolated_cpus
> - * if necessary.
> - */
> - spin_lock_irq(&callback_lock);
> - WRITE_ONCE(child->prs_err, PERR_NOCPUS);
> - if ((old_prs == PRS_ISOLATED) && (parent_prs == PRS_ROOT))
> - isolated_cpus_update(PRS_ISOLATED, PRS_ROOT,
> - child->effective_xcpus);
> - child->partition_root_state = -old_prs;
> - spin_unlock_irq(&callback_lock);
> - notify_partition_change(child, old_prs);
> - continue;
> - }
> - cpumask_andnot(new_ecpus, new_ecpus,
> - child->effective_xcpus);
> - }
> - rcu_read_unlock();
> -}
> -
> /*
> * update_cpumasks_hier - Update effective cpumasks and tasks in the subtree
> * @cs: the cpuset to consider
Acked-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Thanks,
Guopeng
next prev parent reply other threads:[~2026-10-26 9:08 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-25 21:44 [PATCH-next v3 00/11] cgroup/cpuset: Miscellaneous bug fixes & cleanup Waiman Long
2026-10-25 21:44 ` [PATCH-next v3 01/11] cgroup/cpuset: Find furthest isolated ancestor for invalidated isolated partition Waiman Long
2026-10-26 6:33 ` Guopeng Zhang
2026-10-25 21:44 ` [PATCH-next v3 02/11] cgroup/cpuset: Properly compute effective xcpus in update_parent_effective_cpumask() Waiman Long
2026-10-26 6:39 ` Guopeng Zhang
2026-10-25 21:44 ` [PATCH-next v3 03/11] cgroup/cpuset: Fix incorrect effective_cpus bug in update_cpumasks_hier() Waiman Long
2026-10-26 6:46 ` Guopeng Zhang
2026-10-25 21:44 ` [PATCH-next v3 04/11] cgroup/cpuset: Minor fixes to prstate_housekeeping_conflict() Waiman Long
2026-10-26 6:57 ` Guopeng Zhang
2026-10-25 21:44 ` [PATCH-next v3 05/11] selftests/cgroup: Check for a single range nohz_full CPUs before running test matrix Waiman Long
2026-10-25 21:44 ` [PATCH-next v3 06/11] cgroup/cpuset: Prevent recursive call of remote_cpus_update() via update_cpumasks_hier() Waiman Long
2026-10-25 21:44 ` [PATCH-next v3 07/11] cgroup/cpuset: Make sure compute_partition_effective_cpumask() is only called for valid partition Waiman Long
2026-10-26 7:14 ` Guopeng Zhang
2026-10-25 21:44 ` [PATCH-next v3 08/11] cgroup/cpuset: Release invalid isolated CPUs in compute_partition_effective_cpumask() Waiman Long
2026-10-26 8:49 ` Guopeng Zhang
2026-10-25 21:44 ` [PATCH-next v3 09/11] cgroup/cpuset: Release invalid isolated CPUs with a shrunk root partition parent Waiman Long
2026-10-25 23:53 ` [PATCH-next v3.1 " Waiman Long
2026-10-26 8:51 ` Guopeng Zhang
2026-10-25 23:56 ` [PATCH-next v3 " Waiman Long
2026-10-25 21:44 ` [PATCH-next v3 10/11] cgroup/cpuset: Relocate compute_*effective_cpumask() and compute_effective_nodemask() Waiman Long
2026-10-26 9:08 ` Guopeng Zhang [this message]
2026-10-25 21:44 ` [PATCH-next v3 11/11] cgroup/cpuset: Integrate compute_partition_effective_cpumask() into compute_effective_cpumask() Waiman Long
2026-10-26 9:44 ` Guopeng Zhang
2026-10-26 18:26 ` [PATCH-next v3 00/11] cgroup/cpuset: Miscellaneous bug fixes & cleanup Tejun Heo
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=2eb44d83-b5ff-4a6e-94ae-956993da48ea@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 \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.