[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260113093706.GT830755@noisy.programming.kicks-ass.net>
Date: Tue, 13 Jan 2026 10:37:06 +0100
From: Peter Zijlstra <peterz@...radead.org>
To: Gabriele Monaco <gmonaco@...hat.com>
Cc: juri.lelli@...hat.com, Ingo Molnar <mingo@...hat.com>,
linux-kernel@...r.kernel.org, williams@...hat.com
Subject: Re: [PATCH] sched/deadline: Fix server stopping with runnable tasks
On Tue, Jan 13, 2026 at 09:52:01AM +0100, Gabriele Monaco wrote:
> The deadline server can currently stop due to idle although fair tasks
> are runnable. This happens essentially when:
>
> * the server is set to idle, a task wakes up, the server stops
> * a task wakes up, the server sets itself to idle and stops right away
>
> Address both cases by clearing the server idle flag whenever a fair task
> wakes up and accounting also for pending tasks in the definition of idle.
>
> Signed-off-by: Gabriele Monaco <gmonaco@...hat.com>
> ---
>
> This is really quick and dirty but seems to fix it according to the
> models. I also updated the chart to show what is happening here.
> I added the same event (server_resume) to the model.
>
> kernel/sched/deadline.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
> index 138136742871..1070e93350df 100644
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c
> @@ -1376,7 +1376,7 @@ update_stats_dequeue_dl(struct dl_rq *dl_rq, struct sched_dl_entity *dl_se, int
>
> static void update_curr_dl_se(struct rq *rq, struct sched_dl_entity *dl_se, s64 delta_exec)
> {
> - bool idle = rq->curr == rq->idle;
> + bool idle = rq->curr == rq->idle && !rq->nr_running && !rq->ttwu_pending;
This is idle_cpu(), perhaps we can lift that thing into sched.h or so.
> s64 scaled_delta_exec;
>
> if (unlikely(delta_exec <= 0)) {
> @@ -1560,8 +1560,8 @@ void dl_server_update(struct sched_dl_entity *dl_se, s64 delta_exec)
> * | 8 | B:zero_laxity-wait | | |
> * | | | <---+ |
> * | +--------------------------------+ |
> - * | | ^ ^ 2 |
> - * | | 7 | 2 +--------------------+
> + * | | ^ ^ 2 |
> + * | | 7 | 2, 1 +----------------+
> * | v |
> * | +-------------+ |
> * +-- | C:idle-wait | -+
> @@ -1606,8 +1606,11 @@ void dl_server_update(struct sched_dl_entity *dl_se, s64 delta_exec)
> * dl_defer_idle = 0
> *
> *
> - * [1] A->B, A->D
> + * [1] A->B, A->D, C->B
> * dl_server_start()
> + * dl_defer_idle = 0;
> + * if (dl_server_active)
> + * return; // [B]
> * dl_server_active = 1;
> * enqueue_dl_entity()
> * update_dl_entity(WAKEUP)
> @@ -1741,6 +1744,7 @@ void dl_server_start(struct sched_dl_entity *dl_se)
> {
> struct rq *rq = dl_se->rq;
>
> + dl_se->dl_defer_idle = 0;
> if (!dl_server(dl_se) || dl_se->dl_server_active)
> return;
Yeah, this seems sensible.
Let me pick it up and do that idle_cpu() thing.
Powered by blists - more mailing lists