From: sashiko-bot@kernel.org
To: "Jianyong Wu" <wujianyong@hygon.cn>,
"Ingo Molnar" <mingo@redhat.com>,
"Peter Zijlstra" <peterz@infradead.org>,
"Juri Lelli" <juri.lelli@redhat.com>,
"Vincent Guittot" <vincent.guittot@linaro.org>,
"Chen Yu" <yu.c.chen@intel.com>,
"Tim Chen" <tim.c.chen@linux.intel.com>
Cc: "Dietmar Eggemann" <dietmar.eggemann@arm.com>,
"Steven Rostedt" <rostedt@goodmis.org>,
"Ben Segall" <bsegall@google.com>, "Mel Gorman" <mgorman@suse.de>,
"Valentin Schneider" <vschneid@redhat.com>,
"K Prateek Nayak" <kprateek.nayak@amd.com>,
"Shrikanth Hegde" <sshegde@linux.ibm.com>,
"Phil Auld" <pauld@redhat.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"David Hildenbrand" <david@kernel.org>,
maddy@linux.ibm.com, "Michael Ellerman" <mpe@ellerman.id.au>,
ljs@kernel.org, linux-mm@kvack.org, jianyong.wu@outlook.com,
zhongyuan@hygon.cn, huangsj@hygon.cn, wangfengyu@hygon.cn,
yingzhiwei@hygon.cn
Subject: Re: [RFC PATCH v3 13/17] sched/cache: Allow active balance to spread load from a full LLC
Date: Fri, 30 Oct 2026 03:05:04 +0000 [thread overview]
Message-ID: <sashiko-outbox-190207@kernel.org> (raw)
In-Reply-To: <20261029024543.4003980-1-wujianyong@hygon.cn>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] sched/fair: missing 2-CPU utilization gap check in llc_spread_active_balance()
- [Medium] sched/cache: futile active load balance in llc_spread_active_balance()
--
commit 0b23fd14c184de7459085104b19552a73905471e
Author: Jianyong Wu <wujianyong@hygon.cn>
sched/cache: Allow active balance to spread load from a full LLC
This commit introduces llc_spread_active_balance() so migrate_task can trigger
active load balancing across LLCs without waiting for nr_balance_failed to
exceed cache_nice_tries + 2 when the source LLC exceeds the aggregation
threshold and the destination LLC has spare capacity.
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index c3f9ef8798d6c..1e286296cd65c 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -13558,6 +13558,57 @@ imbalanced_active_balance(struct lb_env *env)
> return 0;
> }
>
> +#ifdef CONFIG_SCHED_CACHE
> +/*
> + * Cache-aware aggregation can trigger active balance via migrate_llc_task
> + * without waiting for nr_balance_failed. Spreading load via migrate_task
> + * normally waits for nr_balance_failed to exceed cache_nice_tries + 2.
> + * This can leave one LLC above the aggregation threshold while another
> + * LLC has room.
> + *
> + * Allow that spread when the source is above the aggregation threshold,
> + * the destination has room for one CPU's load, and the source leads by
> + * at least two CPUs' load. The gap prevents one migration from reversing
> + * their utilization ordering and immediately inviting a migration back.
> + * The task migration checks still decide whether the task may move.
> + */
> +static inline bool llc_spread_active_balance(struct lb_env *env)
> +{
> + unsigned long src_util, src_cap, dst_util, dst_cap;
> +
> + if (!sched_cache_enabled())
> + return false;
> +
> + if (env->migration_type != migrate_task)
> + return false;
[Severity: Medium]
Can llc_spread_active_balance() trigger repeated futile active load balance
attempts when env->src_rq->nr_running > 1 and detach_tasks() was vetoed by
cache locality checks?
In sched_balance_rq(), when detach_tasks() fails to pull a task because
can_migrate_task() -> migrate_degrades_llc() -> can_migrate_llcs() returns
mig_forbid, can_migrate_task() sets LBF_LLC_PINNED in env.flags.
When ld_moved == 0, sched_balance_rq() skips incrementing
sd->nr_balance_failed if LBF_LLC_PINNED is set, and then calls
need_active_balance():
kernel/sched/fair.c:sched_balance_rq() {
...
if (idle != CPU_NEWLY_IDLE &&
env.migration_type != migrate_misfit &&
!(env.flags & LBF_LLC_PINNED))
sd->nr_balance_failed++;
if (need_active_balance(&env)) {
...
}
In need_active_balance(), alb_break_llc() only checks can_migrate_llcs() when
env->src_rq->nr_running == 1:
kernel/sched/fair.c:alb_break_llc() {
...
if (env->src_rq->nr_running == 1) {
...
if (can_migrate_llcs(env->src_cpu, env->dst_cpu,
cur, to_pref) == mig_forbid)
return true;
}
return false;
}
When env->src_rq->nr_running > 1, alb_break_llc() returns false, and
llc_spread_active_balance() does not check env->flags & LBF_LLC_PINNED,
env->src_rq->nr_running == 1, or the post-departure and NUMA node constraints
in can_migrate_llcs().
If llc_spread_active_balance() returns true here, sched_balance_rq() queues
active_load_balance_cpu_stop() via stop_one_cpu_nowait() and resets
sd->balance_interval to sd->min_interval. When the CPU stopper runs
detach_one_task() -> can_migrate_task(), sd->nr_balance_failed is still 0, so
migrate_degrades_llc() rejects the migration for the same reason.
Should llc_spread_active_balance() bail out when env->flags & LBF_LLC_PINNED
is set (or check the post-departure state) to avoid kicking the CPU stopper
for a move that can_migrate_task() will reject?
> +
> + if (cpus_share_cache(env->src_cpu, env->dst_cpu))
> + return false;
> +
> + if (!get_llc_stats(env->src_cpu, &src_util, &src_cap) ||
> + !get_llc_stats(env->dst_cpu, &dst_util, &dst_cap))
> + return false;
> +
> + if (fits_llc_capacity(src_util, src_cap, true))
> + return false;
> +
> + /*
> + * Reserve room for one CPU's load at the destination. A two-CPU gap
> + * keeps one migration from reversing the utilization ordering and
> + * causing the task to ping-pong between LLCs.
> + */
> + if (!fits_llc_capacity(dst_util + SCHED_CAPACITY_SCALE, dst_cap, true))
> + return false;
> +
> + return util_greater(src_util, dst_util);
> +}
[Severity: Medium]
Does llc_spread_active_balance() actually enforce the two-CPU utilization gap
described in the comment and commit message?
Moving a task with one full CPU of utilization (SCHED_CAPACITY_SCALE) reduces
src_util by SCHED_CAPACITY_SCALE and increases dst_util by
SCHED_CAPACITY_SCALE, narrowing the gap between src_util and dst_util by
2 * SCHED_CAPACITY_SCALE.
However, the checks here only verify:
1. !fits_llc_capacity(src_util, src_cap, true), meaning src_util > threshold
2. fits_llc_capacity(dst_util + SCHED_CAPACITY_SCALE, dst_cap, true), meaning
dst_util <= threshold - SCHED_CAPACITY_SCALE
3. util_greater(src_util, dst_util), meaning
src_util * 100 > dst_util * (100 + llc_imb_pct)
For equal-capacity LLCs, the two fits_llc_capacity() checks only ensure
src_util - dst_util > SCHED_CAPACITY_SCALE (one CPU of load), and
util_greater() only requires a 20% relative difference (which is smaller than
2 * SCHED_CAPACITY_SCALE whenever dst_util < 10 * SCHED_CAPACITY_SCALE).
For example, on a 4-CPU LLC (cap = 4096, 50% threshold = 2048) with
src_util = 2050 and dst_util = 1024, all three checks pass even though
src_util - dst_util is only 1026 (~1 CPU). Migrating a 1-CPU task (1024)
drops src_util to 1026 (below the aggregation threshold) and raises dst_util
to 2048, reversing the utilization ordering between the two LLCs.
Furthermore, in can_migrate_llcs(), src_util has tsk_util subtracted before
checking the threshold and post-migration ordering:
kernel/sched/fair.c:can_migrate_llcs() {
...
if (src_node == dst_node) {
/* Leave the source LLC at or above the threshold. */
if (fits_llc_capacity(src_util, src_cap, false))
return mig_forbid;
if (util_greater(src_pre, dst_pre) &&
src_util >= dst_util)
return mig_llc;
...
}
Should llc_spread_active_balance() check that src_util remains at or above the
threshold after subtracting SCHED_CAPACITY_SCALE (for example, checking
fits_llc_capacity(src_util - SCHED_CAPACITY_SCALE, src_cap, false) or
explicitly checking src_util >= dst_util + 2 * SCHED_CAPACITY_SCALE) so that
the two-CPU gap is enforced?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029022036.4002331-1-wujianyong@hygon.cn?part=13
next prev parent reply other threads:[~2026-10-30 3:05 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 2:20 [RFC PATCH v3 00/17] sched: Scale cache-aware aggregation at LLC granularity Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 01/17] sched/topology: Add llc_to_node() to translate LLC ID to NUMA node Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 02/17] sched/topology: Build NUMA node affinity sequences Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 03/17] sched/topology: Add an iterator for cached NUMA node affinity rows Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 04/17] sched/topology: Build triangular affinity orders for LLCs in a node Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 05/17] sched/topology: Walk LLCs in NUMA node Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 06/17] sched/cache: Prioritize cache-preferred node selection over LLC selection Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 07/17] sched/topology: Add per-sd scratch for cache-aware load balancing Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 08/17] sched/cache: Introduce helpers for task migration decisions Jianyong Wu
2026-10-30 3:04 ` sashiko-bot
2026-10-29 2:20 ` [RFC PATCH v3 09/17] sched/cache: Introduce rq affinity gain calculation Jianyong Wu
2026-10-30 3:05 ` sashiko-bot
2026-10-29 2:20 ` [RFC PATCH v3 10/17] sched/cache: Pick the source rq/group with the highest affinity gain Jianyong Wu
2026-10-30 3:05 ` sashiko-bot
2026-10-29 2:20 ` [RFC PATCH v3 11/17] sched/cache: Drop prefer_sibling restriction for llc_balance Jianyong Wu
2026-10-29 2:20 ` [RFC PATCH v3 12/17] sched/cache: Apply multi-LLC aggregation policy to task migration Jianyong Wu
2026-10-30 3:05 ` sashiko-bot
2026-10-29 2:45 ` [RFC PATCH v3 13/17] sched/cache: Allow active balance to spread load from a full LLC Jianyong Wu
2026-10-30 3:05 ` sashiko-bot [this message]
2026-10-29 2:50 ` [RFC PATCH v3 14/17] sched/cache: Consider LLC load when selecting a single-task source rq Jianyong Wu
2026-10-29 2:56 ` [RFC PATCH v3 15/17] sched/cache: Include recently used preferred nodes in LLC scans Jianyong Wu
2026-10-30 3:05 ` sashiko-bot
2026-10-29 2:58 ` [RFC PATCH v3 16/17] sched/cache: Drop stale preferred LLC checks Jianyong Wu
2026-10-30 3:05 ` sashiko-bot
2026-10-29 2:59 ` [RFC PATCH v3 17/17] sched/debug: Show cache placement and preferred LLC in /proc/<pid>/sched Jianyong Wu
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=sashiko-outbox-190207@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=bsegall@google.com \
--cc=david@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=huangsj@hygon.cn \
--cc=jianyong.wu@outlook.com \
--cc=juri.lelli@redhat.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=maddy@linux.ibm.com \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=mpe@ellerman.id.au \
--cc=pauld@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=sshegde@linux.ibm.com \
--cc=tim.c.chen@linux.intel.com \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
--cc=wangfengyu@hygon.cn \
--cc=wujianyong@hygon.cn \
--cc=yingzhiwei@hygon.cn \
--cc=yu.c.chen@intel.com \
--cc=zhongyuan@hygon.cn \
/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.