FAILED: patch "[PATCH] sched/cache: Keep nr_pref_llc_running in the runnable domain," failed to apply to 7.2-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 7.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y
git checkout FETCH_HEAD
git cherry-pick -x 0d6526f82c3cdefcca47f73f5fc08dc6f335eac6
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092932-unmanaged-nectar-23d8@gregkh' --subject-prefix 'PATCH 7.2.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0d6526f82c3cdefcca47f73f5fc08dc6f335eac6 Mon Sep 17 00:00:00 2001
From: Tim Chen <[email protected]>
Date: Mon, 21 Sep 2026 17:37:22 -0700
Subject: [PATCH] sched/cache: Keep nr_pref_llc_running in the runnable domain,
to fix LLC mis-scheduling bug
alb_break_llc() decides whether to break LLC preference during active load balance. It does so by testing that every runnable fair task on the source rq prefers its LLC:
env->src_rq->nr_pref_llc_running == env->src_rq->cfs.h_nr_runnable
But the two counters cover different sets. nr_pref_llc_running is updated in account_llc_enqueue()/account_llc_dequeue(), next to cfs_rq->nr_queued, so it follows queued tasks. h_nr_runnable is updated in set_delayed()/ clear_delayed() and drops delay-dequeued tasks.
So under DELAY_DEQUEUE, a preferring task that goes to sleep stays counted in nr_pref_llc_running while h_nr_runnable falls. The equality then breaks, alb_break_llc() returns false, and active balance is free to pull a task off its preferred LLC. Active balance only moves runnable tasks, and this is the only LLC check it consults: once the stopper runs, LBF_ACTIVE_LB skips the per-task test in can_migrate_task(). The runnable set is the one we want.
Fix it on the counter side. A task should be counted in nr_pref_llc_running exactly while it is both queued on its preferred LLC (pref_llc_queued) and runnable (!sched_delayed). Define that membership once in task_pref_llc_runnable(), and adjust the counter only through pref_llc_running_inc()/pref_llc_running_dec() from the four sites that change either input: account_llc_enqueue(), account_llc_dequeue(), set_delayed() and clear_delayed(). Gating every update on the same predicate keeps the delay, wake and dequeue paths from double-counting or underflowing; see the comments at those sites for the ordering.
nr_llc_running and sd->llc_counts are not touched and stay on queued semantics.
kernel/sched/fair.c +58 -5
@@ -1546,6 +1546,28 @@ static bool invalid_llc_nr(struct mm_struct *mm, struct task_struct *p, (scale * per_cpu(sd_llc_size, cpu))); } +/* +* A task counts in nr_pref_llc_running while it is queued on its preferred +* LLC (pref_llc_queued) and runnable (!sched_delayed), keeping the counter in +* the runnable domain so alb_break_llc() can compare it with h_nr_runnable. +*/ +static bool task_pref_llc_runnable (struct task_struct *p) +{ +return p->pref_llc_queued && !p->se.sched_delayed; +} + +static void pref_llc_running_inc (struct rq *rq,struct task_struct *p) +{ +if (task_pref_llc_runnable (p)) + rq->nr_pref_llc_running++; +} + +static void pref_llc_running_dec (struct rq *rq,struct task_struct *p) +{ +if (task_pref_llc_runnable (p)) + rq->nr_pref_llc_running--; +} +static void account_llc_enqueue (struct rq *rq,struct task_struct *p) {int pref_llc, pref_llc_queued;
@@ -1557,7 +1579,6 @@ static void account_llc_enqueue(struct rq *rq, struct task_struct *p) pref_llc_queued = (pref_llc ==task_llc (p)); rq->nr_llc_running++; - rq->nr_pref_llc_running += pref_llc_queued;/* * Record whether p is enqueued on its preferred
@@ -1575,6 +1596,9 @@ static void account_llc_enqueue(struct rq *rq, struct task_struct *p)*/ p->pref_llc_queued = pref_llc_queued; +/* Skipped while delayed; clear_delayed() adds it back on wake. */ +pref_llc_running_inc (rq, p); + sd =rcu_dereference_all (rq->sd);if (sd && (unsigned int )pref_llc < sd->llc_max) sd->llc_counts[pref_llc]++;
@@ -1591,7 +1615,12 @@ static void account_llc_dequeue(struct rq *rq, struct task_struct *p) rq->nr_llc_running--;if (p->pref_llc_queued) { - rq->nr_pref_llc_running--; +/* +* Skipped if still delayed (set_delayed() already removed it); +* clearing pref_llc_queued below also stops clear_delayed() +* from re-adding it. +*/ +pref_llc_running_dec (rq, p);/* * Update the status in case * other logic might query
@@ -1995,6 +2024,7 @@ void init_sched_mm(struct task_struct *p)* polluting account_llc_enqueue(). */ p->preferred_llc =-1 ; + p->pref_llc_queued = 0; }#else /* CONFIG_SCHED_CACHE */
@@ -2016,6 +2046,10 @@ static void account_llc_enqueue(struct rq *rq, struct task_struct *p) {}static void account_llc_dequeue (struct rq *rq,struct task_struct *p) {} +static void pref_llc_running_inc (struct rq *rq,struct task_struct *p) {} + +static void pref_llc_running_dec (struct rq *rq,struct task_struct *p) {} +#endif /* CONFIG_SCHED_CACHE */ /*
@@ -6390,15 +6424,27 @@ static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq);static void set_delayed (struct sched_entity *se) { - se->sched_delayed =1 ; -/* * Delayed se of cfs_rq have no tasks queued on them. * Do not adjust h_nr_runnable since __dequeue_task() * will account it for blocked tasks. +* +* This check can be removed because when flat pick +* patches get merged as only task can get delayed, +* same for clear_delayed(). */ -if (!entity_is_task (se)) +if (!entity_is_task (se)) { + se->sched_delayed =1 ;return ; + } + +/* +* Drop a task leaving the runnable set. +* Needs to be called before sched_delayed is set. +* clear_delayed() mirrors this after clearing the flag. +*/ +pref_llc_running_dec (rq_of (cfs_rq_of (se)),task_of (se)); + se->sched_delayed =1 ;for_each_sched_entity (se) {struct cfs_rq *cfs_rq =cfs_rq_of (se);
@@ -6420,6 +6466,13 @@ static void clear_delayed(struct sched_entity *se)if (!entity_is_task (se))return ; +/* +* Re-add on wake, after sched_delayed is cleared. On a final delayed +* dequeue account_llc_dequeue() already cleared pref_llc_queued, so +* this does nothing. +*/ +pref_llc_running_inc (rq_of (cfs_rq_of (se)),task_of (se)); +for_each_sched_entity (se) {struct cfs_rq *cfs_rq =cfs_rq_of (se);
Quoted 10 lines · On Tue, 2026-09-29 at 13:43 +0200, [email protected] wrote:
The patch below does not apply to the 7.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y git checkout
FETCH_HEAD
git cherry-pick -x0d6526f82c3cdefcca47f73f5fc08dc6f335eac6
This patch seems to apply cleanly on latest 7.2.8:
commit 9a66fdc0d7fd55f54235524a73435af99051e46f (tag: v7.2.8, stable/linux-7.2.y)
[tim@b04f130c83f2 linux]$ git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y From https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux
* branch linux-7.2.y -> FETCH_HEAD
[tim@b04f130c83f2 linux]$ git checkout FETCH_HEAD
HEAD is now at 9a66fdc0d7fd5 Linux 7.2.8
[tim@b04f130c83f2 linux]$ git cherry-pick -x 0d6526f82c3cdefcca47f73f5fc08dc6f335eac6
Auto-merging kernel/sched/fair.c
[detached HEAD 9d0e82dcbce41] sched/cache: Keep nr_pref_llc_running in the runnable domain, to fix LLC mis-scheduling bug
Date: Mon Sep 21 17:37:22 2026 -0700
1 file changed, 58 insertions(+), 5 deletions(-)
Thanks.
Tim
Quoted 192 lines
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092932-unmanaged-nectar-23d8@gregkh' --subject-prefix 'PATCH 7.2.y' 'HEAD^..'Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From
0d6526f82c3cdefcca47f73f5fc08dc6f335eac6Mon Sep 17 00:00:00 2001
From: Tim Chen <[email protected]>
Date: Mon, 21 Sep 2026 17:37:22 -0700
Subject: [PATCH] sched/cache: Keepnr_pref_llc_runningin the runnable domain,
to fix LLC mis-scheduling bug
alb_break_llc()decides whether to break LLC preference during active load balance. It does so by testing that every runnable fair task on the source rq prefers its LLC:env->src_rq->nr_pref_llc_running == env->src_rq->cfs.h_nr_runnableBut the two counters cover different sets.
nr_pref_llc_runningis updated in account_llc_enqueue()/account_llc_dequeue(), next tocfs_rq->nr_queued, so it follows queued tasks.h_nr_runnableis updated in set_delayed()/clear_delayed()and drops delay-dequeued tasks.So under
DELAY_DEQUEUE, a preferring task that goes to sleep stays counted innr_pref_llc_runningwhileh_nr_runnablefalls. The equality then breaks,alb_break_llc()returns false, and active balance is free to pull a task off its preferred LLC. Active balance only moves runnable tasks, and this is the only LLC check it consults: once the stopper runs,LBF_ACTIVE_LBskips the per-task test incan_migrate_task(). The runnable set is the one we want.Fix it on the counter side. A task should be counted in
nr_pref_llc_runningexactly while it is both queued on its preferred LLC (pref_llc_queued) and runnable (!sched_delayed). Define that membership once intask_pref_llc_runnable(), and adjust the counter only through pref_llc_running_inc()/pref_llc_running_dec() from the four sites that change either input:account_llc_enqueue(),account_llc_dequeue(),set_delayed()andclear_delayed(). Gating every update on the same predicate keeps the delay, wake and dequeue paths from double-counting or underflowing; see the comments at those sites for the ordering.
nr_llc_runningandsd->llc_countsare not touched and stay on queued semantics.Fixes 714059f79ff0 ("sched/cache: Handle moving single tasks to/from their preferred LLC")Reported-by Zhan Xusheng <[email protected]>Suggested-by Chen Yu <[email protected]>Signed-off-by Tim Chen <[email protected]>Signed-off-by Peter Zijlstra (Intel) <[email protected]>Signed-off-by Ingo Molnar <[email protected]>Reviewed-by Kayra Cizmeci <[email protected]>Cc <[email protected]> # v7.2.xkernel/sched/fair.c +58
-5@@ -1546,6 +1546,28 @@ static bool invalid_llc_nr(struct mm_struct *mm, struct task_struct *p, (scale * per_cpu(sd_llc_size, cpu))); } +/* +* A task counts in nr_pref_llc_running while it is queued on its preferred +* LLC (pref_llc_queued) and runnable (!sched_delayed), keeping the counter in +* the runnable domain so alb_break_llc() can compare it with h_nr_runnable. +*/ +static bool task_pref_llc_runnable (struct task_struct *p) +{ +return p->pref_llc_queued && !p->se.sched_delayed; +} + +static void pref_llc_running_inc (struct rq *rq,struct task_struct *p) +{ +if (task_pref_llc_runnable (p)) + rq->nr_pref_llc_running++; +} + +static void pref_llc_running_dec (struct rq *rq,struct task_struct *p) +{ +if (task_pref_llc_runnable (p)) + rq->nr_pref_llc_running--; +} +static void account_llc_enqueue (struct rq *rq,struct task_struct *p) {int pref_llc, pref_llc_queued;@@ -1557,7 +1579,6 @@ static void account_llc_enqueue(struct rq *rq, struct task_struct *p) pref_llc_queued = (pref_llc ==task_llc (p)); rq->nr_llc_running++; - rq->nr_pref_llc_running += pref_llc_queued;/* * Record whether p is enqueued on its preferred @@ -1575,6 +1596,9 @@ static void account_llc_enqueue(struct rq *rq, struct task_struct *p)*/ p->pref_llc_queued = pref_llc_queued; +/* Skipped while delayed; clear_delayed() adds it back on wake. */ +pref_llc_running_inc (rq, p); + sd =rcu_dereference_all (rq->sd);if (sd && (unsigned int )pref_llc < sd->llc_max) sd->llc_counts[pref_llc]++;@@ -1591,7 +1615,12 @@ static void account_llc_dequeue(struct rq *rq, struct task_struct *p) rq->nr_llc_running--;if (p->pref_llc_queued) { - rq->nr_pref_llc_running--; +/* +* Skipped if still delayed (set_delayed() already removed it); +* clearing pref_llc_queued below also stops clear_delayed() +* from re-adding it. +*/ +pref_llc_running_dec (rq, p);/* * Update the status in case * other logic might query @@ -1995,6 +2024,7 @@ void init_sched_mm(struct task_struct *p)* polluting account_llc_enqueue(). */ p->preferred_llc =-1 ; + p->pref_llc_queued = 0; }#else /* CONFIG_SCHED_CACHE */ @@ -2016,6 +2046,10 @@ static void account_llc_enqueue(struct rq *rq, struct task_struct *p) {}static void account_llc_dequeue (struct rq *rq,struct task_struct *p) {} +static void pref_llc_running_inc (struct rq *rq,struct task_struct *p) {} + +static void pref_llc_running_dec (struct rq *rq,struct task_struct *p) {} +#endif /* CONFIG_SCHED_CACHE */ /* @@ -6390,15 +6424,27 @@ static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq);static void set_delayed (struct sched_entity *se) { - se->sched_delayed =1 ; -/* * Delayed se of cfs_rq have no tasks queued on them. * Do not adjust h_nr_runnable since __dequeue_task() * will account it for blocked tasks. +* +* This check can be removed because when flat pick +* patches get merged as only task can get delayed, +* same for clear_delayed(). */ -if (!entity_is_task (se)) +if (!entity_is_task (se)) { + se->sched_delayed =1 ;return ; + } + +/* +* Drop a task leaving the runnable set. +* Needs to be called before sched_delayed is set. +* clear_delayed() mirrors this after clearing the flag. +*/ +pref_llc_running_dec (rq_of (cfs_rq_of (se)),task_of (se)); + se->sched_delayed =1 ;for_each_sched_entity (se) {struct cfs_rq *cfs_rq =cfs_rq_of (se);@@ -6420,6 +6466,13 @@ static void clear_delayed(struct sched_entity *se)if (!entity_is_task (se))return ; +/* +* Re-add on wake, after sched_delayed is cleared. On a final delayed +* dequeue account_llc_dequeue() already cleared pref_llc_queued, so +* this does nothing. +*/ +pref_llc_running_inc (rq_of (cfs_rq_of (se)),task_of (se)); +for_each_sched_entity (se) {struct cfs_rq *cfs_rq =cfs_rq_of (se);
Greg KH
maintainerQuoted 17 lines · Tim Chen
Quoted 10 lines · On Tue, 2026-09-29 at 13:43 +0200, [email protected] wrote:
The patch below does not apply to the 7.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y git checkout
FETCH_HEAD
git cherry-pick -x0d6526f82c3cdefcca47f73f5fc08dc6f335eac6This patch seems to apply cleanly on latest 7.2.8:
commit9a66fdc0d7fd55f54235524a73435af99051e46f(tag: v7.2.8, stable/linux-7.2.y)[tim@b04f130c83f2 linux]$ git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y
Quoted 1 line
From https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux
Quoted 9 lines
* branch linux-7.2.y ->
FETCH_HEAD
[tim@b04f130c83f2 linux]$ git checkoutFETCH_HEAD
HEAD is now at9a66fdc0d7fd5Linux 7.2.8
[tim@b04f130c83f2 linux]$ git cherry-pick -x0d6526f82c3cdefcca47f73f5fc08dc6f335eac6
Auto-mergingkernel/sched/fair.c
[detached HEAD9d0e82dcbce41] sched/cache: Keepnr_pref_llc_runningin the runnable domain, to fix LLC mis-scheduling bug
Date: Mon Sep 21 17:37:22 2026 -07001 file changed, 58 insertions(+), 5 deletions(-)
Does not apply now, perhaps due to other patches in the queue?
Again, can you send a series?
thanks,
greg k-h