Re: [BUG] Apparent lost wakeups
From: Vincent Guittot
Date: Tue Oct 13 2026 - 04:45:12 EST
On Tue, 13 Oct 2026 at 10:31, K Prateek Nayak <kprateek.nayak@xxxxxxx> wrote:
>
> Hello Vincent,
>
> On 10/13/2026 1:28 PM, Vincent Guittot wrote:
> >> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> >> index 0f63c30b4324..b37c771c41ad 100644
> >> --- a/kernel/sched/core.c
> >> +++ b/kernel/sched/core.c
> >> @@ -11256,6 +11262,9 @@ void sched_change_end(struct sched_change_ctx *ctx)
> > if (ctx->running) {
> > /*
> > * If this was a class promotion; let the old class
> > * know it got preempted. Note that none of the
> > * switch*_from() methods know the new class and none
> > * of the switch*_to() methods know the old class.
> > */
> > if (sched_class_above(p->sched_class, ctx->class)) {
> > rq->next_class->wakeup_preempt(rq, p, 0);
> > rq->next_class = p->sched_class;
> > }
> > /*
> > * If this was a degradation in class; make sure to
> > * reschedule.
> >> */
> >> if (sched_class_above(ctx->class, p->sched_class))
> >> resched_curr(rq);
> >> + } else if (ctx->queued) {
> >> + /* Check if we need can preempt the current task. */
> >> + wakeup_preempt(rq, p, 0);
> >
> > Isn't what we have for ctx->running above what we also want in this case ?
>
> Ack but with a couple of exceptions:
>
> We may not need a resched_curr() on demotion since the queued task
> isn't running.
I wanted to point the if (sched_class_above(p->sched_class,
ctx->class)) case. I agree that the demotion case is useless if not
running
>
> For a queued but !running task, if the promotion lands at the same
> class as rq->next_class, we'll need to do a
> rq->next_class->wakeup_preempt() to check if we can run it now
> which is also covered by wakeup_preempt().
>
> The ctx->running case seems to have been optimized to avoid doing
> an unnecessary resched / wakeup_preempt() calls when the current
> task is still the best choice.
>
> > Then sched_balance_newidle() will detect it with
> >
> > /* If a higher prio class was modified, restart the pick */
> > if (rq_modified_above(this_rq, &fair_sched_class))
> > pulled_task = -1;
>
> Ack. I'm depending on wakeup_preempt() to set the rq->next_class
> correctly on an upgrade and as you pointed, the newidle will then
> force a RETRY_TASK.
>
> I hope I'm not missing anything.
>
> >
> >> }
> >> } else {
> >> p->sched_class->prio_changed(rq, p, ctx->prio);
>
> --
> Thanks and Regards,
> Prateek
>