* [PATCH v3] sched/stats: Fix run_delay over-count for migrated sched_delayed tasks
@ 2026-09-22 8:24 albin_yang
2026-09-22 10:55 ` Peter Zijlstra
0 siblings, 1 reply; 4+ messages in thread
From: albin_yang @ 2026-09-22 8:24 UTC (permalink / raw)
To: peterz, mingo, juri.lelli, vincent.guittot
Cc: dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
kprateek.nayak, chen.yu, kayracizmeci, mintaohuang, linux-kernel,
albin_yang, albinwyang, Chen Yu
From: Wei Yang <albinwyang@tencent.com>
With DELAY_DEQUEUE, a blocked task stays on the runqueue with
se.sched_delayed set and its sched_info.last_queued is cleared, so the sleep
is not counted into run_delay.
When such a delayed (sleeping) task is migrated across CPUs via the plain
migration paths (move_queued_task / move_queued_task_locked, the latter used
by __migrate_swap_task), activate_task(dst, 0) calls enqueue_task() without
ENQUEUE_RESTORE, re-arming last_queued to the migration timestamp while the
task is still sleeping. The later real wakeup (ENQUEUE_DELAYED) tries to
re-arm last_queued at wakeup time but is suppressed because last_queued is
already non-zero, so sched_info_arrive() folds the whole sleep duration
between migration and wakeup into run_delay.
Load balance is affected too: the sched_delayed check in can_migrate_task()
bails out only when env->migration_type != migrate_load, so it does not
block migration when the type is migrate_load - which active load balance
always uses (its lb_env leaves migration_type at 0 == migrate_load), and
which regular load balance can also use via calculate_imbalance(). Either
way the re-attach goes through attach_task() -> activate_task(rq, p,
ENQUEUE_NOCLOCK), without ENQUEUE_RESTORE.
Fix by not re-arming last_queued for a sched_delayed task in
sched_info_enqueue(). The wakeup path clears sched_delayed before reaching
sched_info_enqueue(), so it still re-arms at the real wakeup time. Plain
runnable tasks are unaffected.
Fixes: 152e11f6df29 ("sched/fair: Implement delayed dequeue")
Reported-by: MingTao Huang <mintaohuang@tencent.com>
Signed-off-by: Wei Yang <albinwyang@tencent.com>
Reviewed-by: Chen Yu <yu.c.chen@intel.com>
Reviewed-by: Kayra Cizmeci <kayracizmeci@gmail.com>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
Changes in v3:
- Collect Reviewed-by from Kayra Cizmeci and K Prateek Nayak.
- Collect Tested-by from K Prateek Nayak.
Changes in v2:
- Correct the load-balance description: sched_delayed tasks are not excluded
from active load balancing. can_migrate_task()'s sched_delayed check only
bails out when env->migration_type != migrate_load, so active load balance
(which always uses migrate_load) still migrates them.
- Collect Reviewed-by from Chen Yu.
v2: https://lore.kernel.org/all/20260920043116.1298017-1-albin_yang@163.com/
v1: https://lore.kernel.org/all/20260909133345.1572954-1-albin_yang@163.com/
kernel/sched/stats.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index ebe0a7765f98..dc626f99ffd9 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -290,7 +290,7 @@ static void sched_info_arrive(struct rq *rq, struct task_struct *t)
*/
static inline void sched_info_enqueue(struct rq *rq, struct task_struct *t)
{
- if (!t->sched_info.last_queued)
+ if (!t->sched_info.last_queued && !t->se.sched_delayed)
t->sched_info.last_queued = rq_clock(rq);
}
--
2.43.7
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3] sched/stats: Fix run_delay over-count for migrated sched_delayed tasks
2026-09-22 8:24 [PATCH v3] sched/stats: Fix run_delay over-count for migrated sched_delayed tasks albin_yang
@ 2026-09-22 10:55 ` Peter Zijlstra
2026-09-22 21:08 ` Kayra Cizmeci
2026-09-23 2:03 ` albin_yang
0 siblings, 2 replies; 4+ messages in thread
From: Peter Zijlstra @ 2026-09-22 10:55 UTC (permalink / raw)
To: albin_yang
Cc: mingo, juri.lelli, vincent.guittot, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, kprateek.nayak, chen.yu,
kayracizmeci, mintaohuang, linux-kernel, albinwyang, Chen Yu
On Tue, Sep 22, 2026 at 04:24:32PM +0800, albin_yang@163.com wrote:
> From: Wei Yang <albinwyang@tencent.com>
>
> With DELAY_DEQUEUE, a blocked task stays on the runqueue with
> se.sched_delayed set and its sched_info.last_queued is cleared, so the sleep
> is not counted into run_delay.
>
> When such a delayed (sleeping) task is migrated across CPUs via the plain
> migration paths (move_queued_task / move_queued_task_locked, the latter used
> by __migrate_swap_task), activate_task(dst, 0) calls enqueue_task() without
> ENQUEUE_RESTORE, re-arming last_queued to the migration timestamp while the
> task is still sleeping. The later real wakeup (ENQUEUE_DELAYED) tries to
> re-arm last_queued at wakeup time but is suppressed because last_queued is
> already non-zero, so sched_info_arrive() folds the whole sleep duration
> between migration and wakeup into run_delay.
>
> Load balance is affected too: the sched_delayed check in can_migrate_task()
> bails out only when env->migration_type != migrate_load, so it does not
> block migration when the type is migrate_load - which active load balance
> always uses (its lb_env leaves migration_type at 0 == migrate_load), and
> which regular load balance can also use via calculate_imbalance(). Either
> way the re-attach goes through attach_task() -> activate_task(rq, p,
> ENQUEUE_NOCLOCK), without ENQUEUE_RESTORE.
>
> Fix by not re-arming last_queued for a sched_delayed task in
> sched_info_enqueue(). The wakeup path clears sched_delayed before reaching
> sched_info_enqueue(), so it still re-arms at the real wakeup time. Plain
> runnable tasks are unaffected.
>
> Fixes: 152e11f6df29 ("sched/fair: Implement delayed dequeue")
> Reported-by: MingTao Huang <mintaohuang@tencent.com>
> Signed-off-by: Wei Yang <albinwyang@tencent.com>
> Reviewed-by: Chen Yu <yu.c.chen@intel.com>
> Reviewed-by: Kayra Cizmeci <kayracizmeci@gmail.com>
> Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
> Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
> ---
> kernel/sched/stats.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
> index ebe0a7765f98..dc626f99ffd9 100644
> --- a/kernel/sched/stats.h
> +++ b/kernel/sched/stats.h
> @@ -290,7 +290,7 @@ static void sched_info_arrive(struct rq *rq, struct task_struct *t)
> */
> static inline void sched_info_enqueue(struct rq *rq, struct task_struct *t)
> {
> - if (!t->sched_info.last_queued)
> + if (!t->sched_info.last_queued && !t->se.sched_delayed)
> t->sched_info.last_queued = rq_clock(rq);
> }
Will we not have a similar problem with proxy exec? That is, would
t->is_blocked be more appropriate?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3] sched/stats: Fix run_delay over-count for migrated sched_delayed tasks
2026-09-22 10:55 ` Peter Zijlstra
@ 2026-09-22 21:08 ` Kayra Cizmeci
2026-09-23 2:03 ` albin_yang
1 sibling, 0 replies; 4+ messages in thread
From: Kayra Cizmeci @ 2026-09-22 21:08 UTC (permalink / raw)
To: peterz
Cc: albin_yang, albinwyang, bsegall, chen.yu, dietmar.eggemann,
juri.lelli, kayracizmeci, kprateek.nayak, linux-kernel, mgorman,
mingo, mintaohuang, rostedt, vincent.guittot, vschneid,
yu.c.chen
Hi Peter,
> Will we not have a similar problem with proxy exec?
> That is, would t->is_blocked be more appropriate?
Yeah.
Only place that sets is_blocked to 1 is try_to_block_task(), which gets only called from __schedule.
Also, we give should_block param. !task_is_blocked(), so
if there are a pointer we return false on try_to_block_task(), so on task_is_blocked() true case,
and that means proxy tasks stay in rq. With blocked 1. So yeah, we have a similar problem on proxy exec.
To the second one tho, I think using task_is_blocked() would be better. Since, the current code
looks to that for whether or not queue the proxy.
And, on some places is_blocked is cleared after enqueu. My brain stopped working 2 hours ago,
this proxy execution stuff combined with delayed fries my brain. So I might be wrong, please correct me if so.
as far as I can tell reading tho. I'm sick of using tho. tho. :-)
Thanks,
Kayra
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3] sched/stats: Fix run_delay over-count for migrated sched_delayed tasks
2026-09-22 10:55 ` Peter Zijlstra
2026-09-22 21:08 ` Kayra Cizmeci
@ 2026-09-23 2:03 ` albin_yang
1 sibling, 0 replies; 4+ messages in thread
From: albin_yang @ 2026-09-23 2:03 UTC (permalink / raw)
To: peterz
Cc: mingo, juri.lelli, vincent.guittot, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, kprateek.nayak, chen.yu,
kayracizmeci, mintaohuang, linux-kernel, albin_yang, albinwyang
Hi Peter,
On Tue, 22 Sep 2026 12:55:22 +0200, Peter Zijlstra wrote:
> Will we not have a similar problem with proxy exec? That is, would
> t->is_blocked be more appropriate?
Yes, there is a similar issue: proxy_migrate_task() re-attaches a blocked
donor via activate_task() without ENQUEUE_RESTORE -- a fake enqueue that
should not update last_queued. Thanks to Kayra for confirming this and for
the task_is_blocked() idea.
But t->is_blocked can't gate it. In ttwu_runnable(), the real wakeup of a
delayed task does its enqueue_task(ENQUEUE_DELAYED) inside the
if (p->is_blocked) branch, and is_blocked is only cleared afterwards in
ttwu_do_wakeup(). So !is_blocked would suppress exactly the re-arm this
patch relies on, and run_delay would never be accounted.
task_is_blocked() does look usable for the proxy case: every waker clears
blocked_on before waking the task (mutex handoff, ww_mutex die/wound,
proxy_needs_return), so it should not be set on a real wakeup enqueue. But
it cannot replace se.sched_delayed -- a delayed sleeper has no blocked_on at
all -- so it would have to be an additional condition rather than a
substitute.
Before adding that I would like to reproduce the proxy case and confirm what
the donor's run_delay should look like: whether the time it spent blocked on
the mutex ought to be dropped like a delayed sleep, or accounted somehow.
Please shed some light on how the proxy case could be dealt with, or should
this patch only focus on the delayed case?
Thanks,
Wei Yang
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-23 2:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-22 8:24 [PATCH v3] sched/stats: Fix run_delay over-count for migrated sched_delayed tasks albin_yang
2026-09-22 10:55 ` Peter Zijlstra
2026-09-22 21:08 ` Kayra Cizmeci
2026-09-23 2:03 ` albin_yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®