* [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
@ 2026-08-01 12:22 Lu Wang
2026-08-03 4:20 ` Chen, Yu C
0 siblings, 1 reply; 7+ messages in thread
From: Lu Wang @ 2026-08-01 12:22 UTC (permalink / raw)
To: linux-kernel
Cc: tim.c.chen, yu.c.chen, peterz, mingo, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, Lu Wang
A passive load-balance pass marks group_llc_balance as migrate_llc_task
and queues active balance when it cannot move a task. The CPU stopper
callback constructs a fresh lb_env, so preserve the migration type on
the runqueue across the asynchronous boundary.
For CAS-directed active balance, reject a candidate whose preferred LLC
does not match the destination LLC. This keeps the fallback from moving
a task away from its preferred LLC.
Fixes: e4c9a4cb244a ("sched/cache: Add migrate_llc_task migration type for cache-aware balancing")
Signed-off-by: Lu Wang <wanglu.priv@gmail.com>
---
v2: add Tim Chen and Chen Yu to Cc
kernel/sched/fair.c | 25 ++++++++++++++++++++++---
kernel/sched/sched.h | 1 +
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d78467ec6..cf036a8a0 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -10645,6 +10645,18 @@ alb_break_llc(struct lb_env *env)
return false;
}
+/*
+ * Returns true if p's preferred LLC does not match the destination CPU,
+ * meaning this task should not be migrated under migrate_llc_task semantics.
+ */
+static inline bool
+migrate_llc_task_wrong_dst(struct task_struct *p, struct lb_env *env)
+{
+ return sched_cache_enabled() &&
+ env->migration_type == migrate_llc_task &&
+ READ_ONCE(p->preferred_llc) != llc_id(env->dst_cpu);
+}
+
/*
* Check if migrating task p from env->src_cpu to
* env->dst_cpu breaks LLC localiy.
@@ -10673,8 +10685,7 @@ static bool migrate_degrades_llc(struct task_struct *p, struct lb_env *env)
* run on env->dst_cpu, skip the tasks do not prefer
* env->dst_cpu, and find the one that prefers.
*/
- if (env->migration_type == migrate_llc_task &&
- READ_ONCE(p->preferred_llc) != llc_id(env->dst_cpu))
+ if (migrate_llc_task_wrong_dst(p, env))
return true;
if (can_migrate_llc_task(env->src_cpu,
@@ -10697,6 +10708,12 @@ alb_break_llc(struct lb_env *env)
return false;
}
+static inline bool
+migrate_llc_task_wrong_dst(struct task_struct *p, struct lb_env *env)
+{
+ return false;
+}
+
static inline bool
migrate_degrades_llc(struct task_struct *p, struct lb_env *env)
{
@@ -10796,7 +10813,7 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
* 4) too many balance attempts have failed.
*/
if (env->flags & LBF_ACTIVE_LB)
- return 1;
+ return !migrate_llc_task_wrong_dst(p, env);
degrades = migrate_degrades_locality(p, env);
if (!degrades) {
@@ -13485,6 +13502,7 @@ static int sched_balance_rq(int this_cpu, struct rq *this_rq,
if (!busiest->active_balance) {
busiest->active_balance = 1;
busiest->push_cpu = this_cpu;
+ busiest->active_balance_type = env.migration_type;
active_balance = 1;
}
@@ -13654,6 +13672,7 @@ static int active_load_balance_cpu_stop(void *data)
.src_rq = busiest_rq,
.idle = CPU_IDLE,
.flags = LBF_ACTIVE_LB,
+ .migration_type = (enum migration_type)busiest_rq->active_balance_type,
};
schedstat_inc(sd->alb_count);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 56acf502b..82084d405 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1266,6 +1266,7 @@ struct rq {
/* For active balancing */
int active_balance;
int push_cpu;
+ int active_balance_type; /* enum migration_type */
struct cpu_stop_work active_balance_work;
/* CPU of this runqueue: */
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
2026-08-01 12:22 [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance Lu Wang
@ 2026-08-03 4:20 ` Chen, Yu C
2026-08-03 10:02 ` Lu Wang
0 siblings, 1 reply; 7+ messages in thread
From: Chen, Yu C @ 2026-08-03 4:20 UTC (permalink / raw)
To: Lu Wang
Cc: tim.c.chen, peterz, mingo, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, linux-kernel, chen.yu@linux.dev
Hi Wang,
Thanks for taking a look at cas,
On 8/1/2026 8:22 PM, Lu Wang wrote:
> A passive load-balance pass marks group_llc_balance as migrate_llc_task
> and queues active balance when it cannot move a task. The CPU stopper
> callback constructs a fresh lb_env, so preserve the migration type on
> the runqueue across the asynchronous boundary.
>
> For CAS-directed active balance, reject a candidate whose preferred LLC
> does not match the destination LLC. This keeps the fallback from moving
> a task away from its preferred LLC.
>
[ ... ]
> static inline bool
> migrate_degrades_llc(struct task_struct *p, struct lb_env *env)
> {
> @@ -10796,7 +10813,7 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
> * 4) too many balance attempts have failed.
> */
> if (env->flags & LBF_ACTIVE_LB)
> - return 1;
> + return !migrate_llc_task_wrong_dst(p, env);
>
When checking whether active load balance is needed in
need_active_balance(),
alb_break_llc() is called to determine if the balance would break LLC
locality
(i.e., prevent a task from being migrated away from its preferred
LLC). Later
in need_active_balance(), if LLC locality is not broken and the task is of
migrate_llc_task type, we force an active load balance. This means that
once
active load balance reaches can_migrate_task(), we want it to always
return true
- this helps the case where the task is the only running one on the
src_cpu. Given
this logic, I do not see the need for the duplicated LLC-locality check in
can_migrate_task() for active load balance. Am I missing anything here?
thanks,
Chenyu
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
2026-08-03 4:20 ` Chen, Yu C
@ 2026-08-03 10:02 ` Lu Wang
2026-08-04 0:10 ` Tim Chen
0 siblings, 1 reply; 7+ messages in thread
From: Lu Wang @ 2026-08-03 10:02 UTC (permalink / raw)
To: yu.c.chen
Cc: tim.c.chen, peterz, mingo, juri.lelli, vincent.guittot,
dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, linux-kernel, chen.yu, Lu Wang
Thanks for the review, Chenyu.
I got interested in CAS because it strikes a good balance between
generic CFS load balancing and strict LLC/CPU affinity.
My understanding is that migrate_llc_task encodes the target
direction of the balance pass, not just "ALB was triggered by CAS".
alb_break_llc() only vetoes ALB when every task on src_rq prefers
staying put (nr_pref_llc_running == cfs.h_nr_runnable); once tasks
have mixed preferences it lets ALB through without checking which
one gets picked. active_load_balance_cpu_stop() then walks
src_rq->cfs_tasks in reverse and takes the first task accepted by
can_migrate_task() — with multiple tasks on src_rq, that's not
necessarily the one whose preferred_llc matches the destination.
My patch threads migration_type through to the stopper and, only
for migrate_llc_task, rejects a candidate whose preferred_llc
doesn't match the destination LLC.
Regarding:
> this helps the case where the task is the only running one on the
> src_cpu
If that single task already prefers the destination LLC, my check
still returns true, so this case is unaffected. The disagreement is
really about what happens when it does not prefer the destination.
That comes down to how we read the semantics of migrate_llc_task:
(a) "migrate a task toward the destination LLC selected by
calculate_imbalance()", or
(b) "this ALB was triggered by CAS's LLC-balance logic, so any
generally-eligible task on src_rq may be pushed"
If (a), the per-task check is needed.
Happy to discuss further.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
2026-08-03 10:02 ` Lu Wang
@ 2026-08-04 0:10 ` Tim Chen
2026-08-04 8:17 ` Chen, Yu C
2026-08-04 8:30 ` Lu Wang
0 siblings, 2 replies; 7+ messages in thread
From: Tim Chen @ 2026-08-04 0:10 UTC (permalink / raw)
To: Lu Wang, yu.c.chen
Cc: peterz, mingo, juri.lelli, vincent.guittot, dietmar.eggemann,
rostedt, bsegall, mgorman, vschneid, kprateek.nayak, linux-kernel,
chen.yu
On Mon, 2026-08-03 at 18:02 +0800, Lu Wang wrote:
> Thanks for the review, Chenyu.
>
> I got interested in CAS because it strikes a good balance between
> generic CFS load balancing and strict LLC/CPU affinity.
>
> My understanding is that migrate_llc_task encodes the target
> direction of the balance pass, not just "ALB was triggered by CAS".
> alb_break_llc() only vetoes ALB when every task on src_rq prefers
> staying put (nr_pref_llc_running == cfs.h_nr_runnable); once tasks
> have mixed preferences it lets ALB through without checking which
> one gets picked. active_load_balance_cpu_stop() then walks
> src_rq->cfs_tasks in reverse and takes the first task accepted by
> can_migrate_task() — with multiple tasks on src_rq, that's not
> necessarily the one whose preferred_llc matches the destination.
>
> My patch threads migration_type through to the stopper and, only
> for migrate_llc_task, rejects a candidate whose preferred_llc
> doesn't match the destination LLC.
>
> Regarding:
> > this helps the case where the task is the only running one on the
> > src_cpu
>
> If that single task already prefers the destination LLC, my check
> still returns true, so this case is unaffected. The disagreement is
> really about what happens when it does not prefer the destination.
> That comes down to how we read the semantics of migrate_llc_task:
>
> (a) "migrate a task toward the destination LLC selected by
> calculate_imbalance()", or
> (b) "this ALB was triggered by CAS's LLC-balance logic, so any
> generally-eligible task on src_rq may be pushed"
The policy of when to break LLC preference locality whether it is in regular
load balance or in active load balance are both encoded in
can_migrate_llc(). Sometimes when an LLC is overloaded, you may
want to move the task off its preferred LLC. Moving a task off its
preferred LLC is not always wrong. Looks like you patch
stop that with migrate_llc_task_wrong_dst().
There is a comment section above can_migrate_llc() to
explain the policy details.
Tim
>
> If (a), the per-task check is needed.
>
> Happy to discuss further.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
2026-08-04 0:10 ` Tim Chen
@ 2026-08-04 8:17 ` Chen, Yu C
2026-08-04 8:30 ` Lu Wang
1 sibling, 0 replies; 7+ messages in thread
From: Chen, Yu C @ 2026-08-04 8:17 UTC (permalink / raw)
To: Tim Chen, Lu Wang
Cc: peterz, mingo, juri.lelli, vincent.guittot, dietmar.eggemann,
rostedt, bsegall, mgorman, vschneid, kprateek.nayak, linux-kernel,
chen.yu
On 8/4/2026 8:10 AM, Tim Chen wrote:
> On Mon, 2026-08-03 at 18:02 +0800, Lu Wang wrote:
>> Thanks for the review, Chenyu.
>>
>> I got interested in CAS because it strikes a good balance between
>> generic CFS load balancing and strict LLC/CPU affinity.
>>
>> My understanding is that migrate_llc_task encodes the target
>> direction of the balance pass, not just "ALB was triggered by CAS".
>> alb_break_llc() only vetoes ALB when every task on src_rq prefers
>> staying put (nr_pref_llc_running == cfs.h_nr_runnable); once tasks
>> have mixed preferences it lets ALB through without checking which
>> one gets picked. active_load_balance_cpu_stop() then walks
>> src_rq->cfs_tasks in reverse and takes the first task accepted by
>> can_migrate_task() — with multiple tasks on src_rq, that's not
>> necessarily the one whose preferred_llc matches the destination.
>>
>> My patch threads migration_type through to the stopper and, only
>> for migrate_llc_task, rejects a candidate whose preferred_llc
>> doesn't match the destination LLC.
>>
>> Regarding:
>>> this helps the case where the task is the only running one on the
>>> src_cpu
>>
>> If that single task already prefers the destination LLC, my check
>> still returns true, so this case is unaffected. The disagreement is
>> really about what happens when it does not prefer the destination.
>> That comes down to how we read the semantics of migrate_llc_task:
>>
>> (a) "migrate a task toward the destination LLC selected by
>> calculate_imbalance()", or
>> (b) "this ALB was triggered by CAS's LLC-balance logic, so any
>> generally-eligible task on src_rq may be pushed"
>
> The policy of when to break LLC preference locality whether it is in regular
> load balance or in active load balance are both encoded in
> can_migrate_llc(). Sometimes when an LLC is overloaded, you may
> want to move the task off its preferred LLC. Moving a task off its
> preferred LLC is not always wrong. Looks like you patch
> stop that with migrate_llc_task_wrong_dst().
> There is a comment section above can_migrate_llc() to
> explain the policy details.
>
Yes. Besides, if I understand correctly, I suppose Lu Wang was
referring to the following scenario:
src_rq has 2 runnable tasks, p1 and p2. p1 prefers dst_rq (dst_llc),
while p2 prefers src_rq (src_llc). In this case, migrate_llc_task is
set because src_rq has at least one task, p1, that wants to migrate
to dst_rq. In ALB, can_migrate_task() found p2 and returns true for p2
thus moves p2 out of its preferred LLC.
Here is the reason that it might not happen IMO:
Firstly, before ALB is triggered, the generic (passive) load balance is
triggered.
It iterates over p1 and p2 on src_rq to see if it can move any one of
them to
dst_rq, and in most cases it succeeds in moving p1 to dst_cpu. As a
result, ALB
will not be triggered. So the scenario Lu Wang was worried about will
not happen.
On the other hand, even if there is only p2 running on src_cpu and it
prefers
src_cpu (src_llc), the passive load balance will fail, and ALB will be
triggered.
However, alb_break_llc() will return true because p2 wants to stay and
it is the
only running task, so ALB will not be triggered neither. So the scenario
Lu Wang
worried about will not happen.
thanks,
Chenyu
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
2026-08-04 0:10 ` Tim Chen
2026-08-04 8:17 ` Chen, Yu C
@ 2026-08-04 8:30 ` Lu Wang
1 sibling, 0 replies; 7+ messages in thread
From: Lu Wang @ 2026-08-04 8:30 UTC (permalink / raw)
To: tim.c.chen
Cc: bsegall, chen.yu, dietmar.eggemann, juri.lelli, kprateek.nayak,
linux-kernel, mgorman, mingo, peterz, rostedt, vincent.guittot,
vschneid, yu.c.chen, Lu Wang
Thanks, Tim.
On Mon, 2026-08-03 at 17:10 -0700, Tim Chen wrote:
> On Mon, 2026-08-03 at 18:02 +0800, Lu Wang wrote:
> > Thanks for the review, Chenyu.
> >
> > I got interested in CAS because it strikes a good balance between
> > generic CFS load balancing and strict LLC/CPU affinity.
> >
> > My understanding is that migrate_llc_task encodes the target
> > direction of the balance pass, not just "ALB was triggered by CAS".
> > alb_break_llc() only vetoes ALB when every task on src_rq prefers
> > staying put (nr_pref_llc_running == cfs.h_nr_runnable); once tasks
> > have mixed preferences it lets ALB through without checking which
> > one gets picked. active_load_balance_cpu_stop() then walks
> > src_rq->cfs_tasks in reverse and takes the first task accepted by
> > can_migrate_task() — with multiple tasks on src_rq, that's not
> > necessarily the one whose preferred_llc matches the destination.
> >
> > My patch threads migration_type through to the stopper and, only
> > for migrate_llc_task, rejects a candidate whose preferred_llc
> > doesn't match the destination LLC.
> >
> > Regarding:
> > > this helps the case where the task is the only running one on the
> > > src_cpu
> >
> > If that single task already prefers the destination LLC, my check
> > still returns true, so this case is unaffected. The disagreement is
> > really about what happens when it does not prefer the destination.
> > That comes down to how we read the semantics of migrate_llc_task:
> >
> > (a) "migrate a task toward the destination LLC selected by
> > calculate_imbalance()", or
> > (b) "this ALB was triggered by CAS's LLC-balance logic, so any
> > generally-eligible task on src_rq may be pushed"
>
> The policy of when to break LLC preference locality whether it is in
> regular load balance or in active load balance are both encoded in
> can_migrate_llc(). Sometimes when an LLC is overloaded, you may
> want to move the task off its preferred LLC. Moving a task off its
> preferred LLC is not always wrong. Looks like you patch
> stop that with migrate_llc_task_wrong_dst().
> There is a comment section above can_migrate_llc() to
> explain the policy details.
To clarify the scope: my patch only adds a stricter check for the
migrate_llc_task type during migration.
llc_balance() triggers this classification as long as there are
tasks whose preferred LLC is the destination, independent of load
or utilization. So it sits at the end of the balancing priority
chain. The comment above group_llc_balance's priority assignment,
which you wrote, says:
"The priority of group_llc_balance is lower than that of
[other types]... This is because group_llc_balance may
exacerbate load imbalance."
This makes clear that group_llc_balance was not designed to correct
load imbalance — it explicitly acknowledges it may worsen it.
For the other migration types that do address load imbalance
(migrate_load, migrate_util, migrate_task, migrate_misfit), my patch
doesn't change their logic at all — the check only fires when
env->migration_type == migrate_llc_task.
Is my understanding incorrect here?
Wang
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance
@ 2026-08-01 12:17 Lu Wang
0 siblings, 0 replies; 7+ messages in thread
From: Lu Wang @ 2026-08-01 12:17 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, peterz, juri.lelli, vincent.guittot, dietmar.eggemann,
rostedt, bsegall, mgorman, vschneid, kprateek.nayak, Lu Wang
A passive load-balance pass marks group_llc_balance as migrate_llc_task
and queues active balance when it cannot move a task. The CPU stopper
callback constructs a fresh lb_env, so preserve the migration type on
the runqueue across the asynchronous boundary.
For CAS-directed active balance, reject a candidate whose preferred LLC
does not match the destination LLC. This keeps the fallback from moving
a task away from its preferred LLC.
Fixes: e4c9a4cb244a ("sched/cache: Add migrate_llc_task migration type for cache-aware balancing")
Signed-off-by: Lu Wang <wanglu.priv@gmail.com>
---
kernel/sched/fair.c | 25 ++++++++++++++++++++++---
kernel/sched/sched.h | 1 +
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d78467ec6..cf036a8a0 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -10645,6 +10645,18 @@ alb_break_llc(struct lb_env *env)
return false;
}
+/*
+ * Returns true if p's preferred LLC does not match the destination CPU,
+ * meaning this task should not be migrated under migrate_llc_task semantics.
+ */
+static inline bool
+migrate_llc_task_wrong_dst(struct task_struct *p, struct lb_env *env)
+{
+ return sched_cache_enabled() &&
+ env->migration_type == migrate_llc_task &&
+ READ_ONCE(p->preferred_llc) != llc_id(env->dst_cpu);
+}
+
/*
* Check if migrating task p from env->src_cpu to
* env->dst_cpu breaks LLC localiy.
@@ -10673,8 +10685,7 @@ static bool migrate_degrades_llc(struct task_struct *p, struct lb_env *env)
* run on env->dst_cpu, skip the tasks do not prefer
* env->dst_cpu, and find the one that prefers.
*/
- if (env->migration_type == migrate_llc_task &&
- READ_ONCE(p->preferred_llc) != llc_id(env->dst_cpu))
+ if (migrate_llc_task_wrong_dst(p, env))
return true;
if (can_migrate_llc_task(env->src_cpu,
@@ -10697,6 +10708,12 @@ alb_break_llc(struct lb_env *env)
return false;
}
+static inline bool
+migrate_llc_task_wrong_dst(struct task_struct *p, struct lb_env *env)
+{
+ return false;
+}
+
static inline bool
migrate_degrades_llc(struct task_struct *p, struct lb_env *env)
{
@@ -10796,7 +10813,7 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
* 4) too many balance attempts have failed.
*/
if (env->flags & LBF_ACTIVE_LB)
- return 1;
+ return !migrate_llc_task_wrong_dst(p, env);
degrades = migrate_degrades_locality(p, env);
if (!degrades) {
@@ -13485,6 +13502,7 @@ static int sched_balance_rq(int this_cpu, struct rq *this_rq,
if (!busiest->active_balance) {
busiest->active_balance = 1;
busiest->push_cpu = this_cpu;
+ busiest->active_balance_type = env.migration_type;
active_balance = 1;
}
@@ -13654,6 +13672,7 @@ static int active_load_balance_cpu_stop(void *data)
.src_rq = busiest_rq,
.idle = CPU_IDLE,
.flags = LBF_ACTIVE_LB,
+ .migration_type = (enum migration_type)busiest_rq->active_balance_type,
};
schedstat_inc(sd->alb_count);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 56acf502b..82084d405 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1266,6 +1266,7 @@ struct rq {
/* For active balancing */
int active_balance;
int push_cpu;
+ int active_balance_type; /* enum migration_type */
struct cpu_stop_work active_balance_work;
/* CPU of this runqueue: */
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-04 8:30 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-01 12:22 [PATCH] sched/cache: honor migrate_llc_task semantics in active load balance Lu Wang
2026-08-03 4:20 ` Chen, Yu C
2026-08-03 10:02 ` Lu Wang
2026-08-04 0:10 ` Tim Chen
2026-08-04 8:17 ` Chen, Yu C
2026-08-04 8:30 ` Lu Wang
-- strict thread matches above, loose matches on Subject: below --
2026-08-01 12:17 Lu Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox