[PATCH 03/20 v3] sched/eevdf: Reset lag at wakeup when migrating and prev has been idle

From: Vincent Guittot

Date: Fri Nov 06 2026 - 10:25:01 EST


When prev CPU entered idle while a task was sleeping, we assume that the
latter received enough running time and the lag can be cleared similarly to
what happens for a negative lag.
While migrating the waking task to a new cpu, Check if prev CPU entered
idle in the meantime.

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

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 79f53811274e..945de0215abb 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -932,6 +932,27 @@ bool update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se)
static inline unsigned long cfs_rq_load_avg(struct cfs_rq *cfs_rq);
static unsigned long task_h_load(struct task_struct *p);

+static __always_inline
+void entity_clear_lag(struct task_struct *p)
+{
+ struct sched_entity *se;
+ struct cfs_rq *cfs_rq;
+
+ if (READ_ONCE(p->__state) != TASK_WAKING)
+ return;
+
+ se = &p->se;
+ /* Negative lag implies delayed dequeue */
+ if (se->vlag <= 0)
+ return;
+
+ cfs_rq = &task_rq(p)->cfs;
+
+ /* CPU has been idle in between so the lag has been removed */
+ if (se->vlag_seq != READ_ONCE(cfs_rq->idle_seq))
+ se->vlag = 0;
+}
+
static __always_inline
void decay_entity_lag(struct cfs_rq *cfs_rq, struct task_struct *p, int flags)
{
@@ -10049,6 +10070,12 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu)
struct sched_entity *se = &p->se;

if (!task_on_rq_migrating(p)) {
+ /*
+ * Clear the positive lag of a waking task before migrating to
+ * the new cpu.
+ */
+ entity_clear_lag(p);
+
remove_entity_load_avg(se);

/*
--
2.53.0