[PATCH 5/8] sched/eevdf: Reset lag when waking up on idle cpu

From: Vincent Guittot

Date: Mon Sep 21 2026 - 11:50:45 EST


When several tasks wake up simultaneously on an idle CPU, their final vlag
will depend of the ordering as the first one will lose its lag but not
the next ones.
Reset the lag when the enqueue happens while no fair task has already been
picked et set as the running task.

As a typical example:
CPU0 is idle
TA with vlag 0ms and TB with vlag 5ms wake up on CPU0 simultaneously.
Depending which grab the lock 1st the behavior will be different:
If TA is enqueued 1st, TB will be enqueued with a positive lag and will
be picked 1st.
But if TB is enqueued 1st, it will loose its positive vlag and both TA and
TB will have 0 vlag when fair will pick a task.

Signed-off-by: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
---
kernel/sched/fair.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 4230954d10d0..739a3af60520 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -900,7 +900,7 @@ static __always_inline
void decay_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
{
s64 vlag = se->vlag;
- s64 delta_exec;
+ struct rq *rq;

WARN_ON_ONCE(se->on_rq);

@@ -908,18 +908,25 @@ void decay_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
if (vlag <= 0)
return;

- if (flags & ENQUEUE_MIGRATED)
- return;
+ rq = rq_of(cfs_rq);

- /* Compute the sleep time */
- delta_exec = rq_clock_task(rq_of(cfs_rq)) - se->exec_start;
- if (unlikely(delta_exec <= 0))
- return;
+ if (rq->curr == rq->idle) {
+ /* You can't claim any lag when waking on idle CPU */
+ vlag = 0;
+ } else if (!(flags & ENQUEUE_MIGRATED)) {
+ u64 now = rq_clock_task(rq);
+ s64 delta_exec;

- vlag -= calc_delta_fair(delta_exec, se);
+ /* Compute the sleep time */
+ delta_exec = now - se->exec_start;
+ if (unlikely(delta_exec <= 0))
+ return;

- /* vlag can't become negative while sleeping */
- se->vlag = max(0, vlag);
+ vlag -= calc_delta_fair(delta_exec, se);
+
+ /* vlag can't become neg while sleeping */
+ se->vlag = max(0, vlag);
+ }
}

/*
--
2.53.0