Messages in this thread Patch in this message | | | Date | Fri, 30 Aug 2019 13:24:37 +0200 | From | Peter Zijlstra <> | Subject | Re: [RFC][PATCH 12/13] sched/deadline: Introduce deadline servers |
| |
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)
| |