Re: [BUG] Apparent lost wakeups
From: Peter Zijlstra
Date: Tue Oct 13 2026 - 07:02:01 EST
On Tue, Oct 13, 2026 at 09:58:25AM +0200, 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 ?
> 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;
>
Ah, I'm maybe slowly starting to see the shape of this. Does something
like so make sense?
That is, any task on the rq cares about promotion, only the current
running task cares about demotion.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 047fbe8ef298..2a8bf562a769 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -11261,7 +11261,7 @@ void sched_change_end(struct sched_change_ctx *ctx)
if (p->sched_class->switched_to)
p->sched_class->switched_to(rq, p);
- if (ctx->running) {
+ if (ctx->queued) {
/*
* If this was a class promotion; let the old class
* know it got preempted. Note that none of the
@@ -11272,6 +11272,9 @@ void sched_change_end(struct sched_change_ctx *ctx)
rq->next_class->wakeup_preempt(rq, p, 0);
rq->next_class = p->sched_class;
}
+ }
+
+ if (ctx->running) {
/*
* If this was a degradation in class; make sure to
* reschedule.