Re: [RFC][PATCH 12/13] sched/deadline: Introduce deadline servers

From: Peter Zijlstra
Date: Fri Aug 30 2019 - 07:25:02 EST


On Thu, Aug 08, 2019 at 11:45:46AM +0200, Juri Lelli wrote:
> I'd like to take this last sentence back, I was able to run a few boot +
> hackbench + shutdown cycles with the following applied (guess too much
> debug printks around before).

I've changed that slightly; the merged delta looks like:


--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3913,6 +3913,13 @@ pick_next_task(struct rq *rq, struct tas
if (unlikely(!p))
p = idle_sched_class.pick_next_task(rq, prev, rf);

+ /*
+ * This is the fast path; it cannot be a DL server pick;
+ * therefore even if @p == @prev, ->server must be NULL.
+ */
+ if (prev->server)
+ p->server = NULL;
+
return p;
}

@@ -3925,13 +3932,18 @@ pick_next_task(struct rq *rq, struct tas
if (!rq->nr_running)
newidle_balance(rq, rf);

+ /*
+ * We've updated @prev and no longer need the server link, clear it.
+ * Must be done before ->pick_next_task() because that can (re)set
+ * ->server.
+ */
+ if (prev->server)
+ prev->server = NULL;
+
for_each_class(class) {
p = class->pick_next_task(rq, NULL, NULL);
- if (p) {
- if (p->sched_class == class && p->server)
- p->server = NULL;
+ if (p)
return p;
- }
}

/* The idle class should always have a runnable task: */
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1312,6 +1312,10 @@ void dl_server_update(struct sched_dl_en

void dl_server_start(struct sched_dl_entity *dl_se)
{
+ if (!dl_server(dl_se)) {
+ dl_se->dl_server = 1;
+ setup_new_dl_entity(dl_se);
+ }
enqueue_dl_entity(dl_se, dl_se, ENQUEUE_WAKEUP);
}

@@ -1324,12 +1328,9 @@ void dl_server_init(struct sched_dl_enti
dl_server_has_tasks_f has_tasks,
dl_server_pick_f pick)
{
- dl_se->dl_server = 1;
dl_se->rq = rq;
dl_se->server_has_tasks = has_tasks;
dl_se->server_pick = pick;
-
- setup_new_dl_entity(dl_se);
}

/*
@@ -2855,6 +2856,7 @@ static void __dl_clear_params(struct sch
dl_se->dl_yielded = 0;
dl_se->dl_non_contending = 0;
dl_se->dl_overrun = 0;
+ dl_se->dl_server = 0;
}

void init_dl_entity(struct sched_dl_entity *dl_se)