* [PATCH] sched/fair: Update zero_vruntime after clearing on_rq in dequeue_entity()
@ 2026-03-19 11:21 Zicheng Qu
2026-03-23 7:52 ` Vincent Guittot
0 siblings, 1 reply; 4+ messages in thread
From: Zicheng Qu @ 2026-03-19 11:21 UTC (permalink / raw)
To: mingo, peterz, juri.lelli, vincent.guittot, dietmar.eggemann,
rostedt, bsegall, mgorman, vschneid, linux-kernel
Cc: tanghui20, zhangqiao22, quzicheng
When dequeuing the current entity (cfs_rq->curr) in dequeue_entity(),
the cfs_rq->zero_vruntime is updated via update_entity_lag() ->
avg_vruntime() -> update_zero_vruntime() while curr->on_rq is still 1.
This means the current entity is still included in the zero_vruntime
calculation.
However, immediately after this, curr->on_rq is set to 0, which should
change the avg_vruntime() result. Without re-updating zero_vruntime, the
stale value may be used in subsequent task selection paths:
schedule() -> ... -> pick_task_fair() -> pick_next_entity() ->
pick_eevdf() -> vruntime_eligible()
If entity_tick() -> avg_vruntime() -> update_zero_vruntime() is not
triggered in time between dequeue and the next pick, vruntime_eligible()
may use an inaccurate cfs_rq->zero_vruntime. This can potentially cause
all tasks to appear ineligible, leading to NULL pointer dereference.
Add an explicit avg_vruntime(cfs_rq) call after clearing curr->on_rq to
ensure cfs_rq->zero_vruntime is properly updated before the next pick.
Fixes: 147f3efaa241 ("sched/fair: Implement an EEVDF-like scheduling policy")
Signed-off-by: Zicheng Qu <quzicheng@huawei.com>
Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com>
---
kernel/sched/fair.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index bf948db905ed..f8070767c2f4 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5461,6 +5461,9 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
if (se != cfs_rq->curr)
__dequeue_entity(cfs_rq, se);
se->on_rq = 0;
+ /* update the cfs_rq->zero_vruntime again after curr->on_rq = 0 */
+ if (se == cfs_rq->curr)
+ avg_vruntime(cfs_rq);
account_entity_dequeue(cfs_rq, se);
/* return excess runtime on last dequeue */
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] sched/fair: Update zero_vruntime after clearing on_rq in dequeue_entity()
2026-03-19 11:21 [PATCH] sched/fair: Update zero_vruntime after clearing on_rq in dequeue_entity() Zicheng Qu
@ 2026-03-23 7:52 ` Vincent Guittot
2026-03-23 9:57 ` Peter Zijlstra
0 siblings, 1 reply; 4+ messages in thread
From: Vincent Guittot @ 2026-03-23 7:52 UTC (permalink / raw)
To: Zicheng Qu
Cc: mingo, peterz, juri.lelli, dietmar.eggemann, rostedt, bsegall,
mgorman, vschneid, linux-kernel, tanghui20, zhangqiao22
On Thu, 19 Mar 2026 at 12:43, Zicheng Qu <quzicheng@huawei.com> wrote:
>
> When dequeuing the current entity (cfs_rq->curr) in dequeue_entity(),
> the cfs_rq->zero_vruntime is updated via update_entity_lag() ->
> avg_vruntime() -> update_zero_vruntime() while curr->on_rq is still 1.
> This means the current entity is still included in the zero_vruntime
> calculation.
curr is not included in zero_vruntime but added when computing
avg_vruntime so zero_vruntime is not impacted when curr is dequeued
>
> However, immediately after this, curr->on_rq is set to 0, which should
> change the avg_vruntime() result. Without re-updating zero_vruntime, the
> stale value may be used in subsequent task selection paths:
>
> schedule() -> ... -> pick_task_fair() -> pick_next_entity() ->
> pick_eevdf() -> vruntime_eligible()
>
> If entity_tick() -> avg_vruntime() -> update_zero_vruntime() is not
> triggered in time between dequeue and the next pick, vruntime_eligible()
> may use an inaccurate cfs_rq->zero_vruntime. This can potentially cause
> all tasks to appear ineligible, leading to NULL pointer dereference.
>
> Add an explicit avg_vruntime(cfs_rq) call after clearing curr->on_rq to
> ensure cfs_rq->zero_vruntime is properly updated before the next pick.
>
> Fixes: 147f3efaa241 ("sched/fair: Implement an EEVDF-like scheduling policy")
> Signed-off-by: Zicheng Qu <quzicheng@huawei.com>
> Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com>
> ---
> kernel/sched/fair.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index bf948db905ed..f8070767c2f4 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -5461,6 +5461,9 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
> if (se != cfs_rq->curr)
> __dequeue_entity(cfs_rq, se);
> se->on_rq = 0;
> + /* update the cfs_rq->zero_vruntime again after curr->on_rq = 0 */
> + if (se == cfs_rq->curr)
> + avg_vruntime(cfs_rq);
> account_entity_dequeue(cfs_rq, se);
>
> /* return excess runtime on last dequeue */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] sched/fair: Update zero_vruntime after clearing on_rq in dequeue_entity()
2026-03-23 7:52 ` Vincent Guittot
@ 2026-03-23 9:57 ` Peter Zijlstra
2026-03-23 10:34 ` Vincent Guittot
0 siblings, 1 reply; 4+ messages in thread
From: Peter Zijlstra @ 2026-03-23 9:57 UTC (permalink / raw)
To: Vincent Guittot
Cc: Zicheng Qu, mingo, juri.lelli, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, linux-kernel, tanghui20, zhangqiao22
On Mon, Mar 23, 2026 at 08:52:21AM +0100, Vincent Guittot wrote:
> On Thu, 19 Mar 2026 at 12:43, Zicheng Qu <quzicheng@huawei.com> wrote:
> >
> > When dequeuing the current entity (cfs_rq->curr) in dequeue_entity(),
> > the cfs_rq->zero_vruntime is updated via update_entity_lag() ->
> > avg_vruntime() -> update_zero_vruntime() while curr->on_rq is still 1.
> > This means the current entity is still included in the zero_vruntime
> > calculation.
>
> curr is not included in zero_vruntime but added when computing
> avg_vruntime so zero_vruntime is not impacted when curr is dequeued
It is, we explicitly add curr back in.
> > However, immediately after this, curr->on_rq is set to 0, which should
> > change the avg_vruntime() result. Without re-updating zero_vruntime, the
> > stale value may be used in subsequent task selection paths:
> >
> > schedule() -> ... -> pick_task_fair() -> pick_next_entity() ->
> > pick_eevdf() -> vruntime_eligible()
> >
> > If entity_tick() -> avg_vruntime() -> update_zero_vruntime() is not
> > triggered in time between dequeue and the next pick, vruntime_eligible()
> > may use an inaccurate cfs_rq->zero_vruntime. This can potentially cause
> > all tasks to appear ineligible, leading to NULL pointer dereference.
This makes no sense.
One entity worth of vruntime should not affect things to the point of
overrun. Yes, it is true that zero_vruntime != avg_vruntime() right
after a dequeue, but that doesn't matter.
vruntime_eligible() does the same math that avg_vruntime() does and
takes this difference into account.
As long as zero_vruntime is close 'enough' to avg_vruntime, all the
deltas are small and nothing overflows.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] sched/fair: Update zero_vruntime after clearing on_rq in dequeue_entity()
2026-03-23 9:57 ` Peter Zijlstra
@ 2026-03-23 10:34 ` Vincent Guittot
0 siblings, 0 replies; 4+ messages in thread
From: Vincent Guittot @ 2026-03-23 10:34 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Zicheng Qu, mingo, juri.lelli, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, linux-kernel, tanghui20, zhangqiao22
On Mon, 23 Mar 2026 at 10:57, Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Mon, Mar 23, 2026 at 08:52:21AM +0100, Vincent Guittot wrote:
> > On Thu, 19 Mar 2026 at 12:43, Zicheng Qu <quzicheng@huawei.com> wrote:
> > >
> > > When dequeuing the current entity (cfs_rq->curr) in dequeue_entity(),
> > > the cfs_rq->zero_vruntime is updated via update_entity_lag() ->
> > > avg_vruntime() -> update_zero_vruntime() while curr->on_rq is still 1.
> > > This means the current entity is still included in the zero_vruntime
> > > calculation.
> >
> > curr is not included in zero_vruntime but added when computing
> > avg_vruntime so zero_vruntime is not impacted when curr is dequeued
>
> It is, we explicitly add curr back in.
yeah, i should have taken one more coffee before replying
>
> > > However, immediately after this, curr->on_rq is set to 0, which should
> > > change the avg_vruntime() result. Without re-updating zero_vruntime, the
> > > stale value may be used in subsequent task selection paths:
> > >
> > > schedule() -> ... -> pick_task_fair() -> pick_next_entity() ->
> > > pick_eevdf() -> vruntime_eligible()
> > >
> > > If entity_tick() -> avg_vruntime() -> update_zero_vruntime() is not
> > > triggered in time between dequeue and the next pick, vruntime_eligible()
> > > may use an inaccurate cfs_rq->zero_vruntime. This can potentially cause
> > > all tasks to appear ineligible, leading to NULL pointer dereference.
>
> This makes no sense.
>
> One entity worth of vruntime should not affect things to the point of
> overrun. Yes, it is true that zero_vruntime != avg_vruntime() right
> after a dequeue, but that doesn't matter.
>
> vruntime_eligible() does the same math that avg_vruntime() does and
> takes this difference into account.
>
> As long as zero_vruntime is close 'enough' to avg_vruntime, all the
> deltas are small and nothing overflows.
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-23 10:35 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-19 11:21 [PATCH] sched/fair: Update zero_vruntime after clearing on_rq in dequeue_entity() Zicheng Qu
2026-03-23 7:52 ` Vincent Guittot
2026-03-23 9:57 ` Peter Zijlstra
2026-03-23 10:34 ` Vincent Guittot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome