Skip to content

Commit 9f239df

Browse files
jlelliPeter Zijlstra
authored andcommitted
sched/deadline: Initialize dl_servers after SMP
dl-servers are currently initialized too early at boot when CPUs are not fully up (only boot CPU is). This results in miscalculation of per runqueue DEADLINE variables like extra_bw (which needs a stable CPU count). Move initialization of dl-servers later on after SMP has been initialized and CPUs are all online, so that CPU count is stable and DEADLINE variables can be computed correctly. Fixes: d741f29 ("sched/fair: Fair server interface") Reported-by: Marcel Ziswiler <[email protected]> Signed-off-by: Juri Lelli <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Waiman Long <[email protected]> Tested-by: Marcel Ziswiler <[email protected]> # nuc & rock5b Link: https://lore.kernel.org/r/[email protected]
1 parent 2885daf commit 9f239df

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

kernel/sched/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8371,6 +8371,8 @@ void __init sched_init_smp(void)
83718371
init_sched_rt_class();
83728372
init_sched_dl_class();
83738373

8374+
sched_init_dl_servers();
8375+
83748376
sched_smp_initialized = true;
83758377
}
83768378

kernel/sched/deadline.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se)
761761
struct dl_rq *dl_rq = dl_rq_of_se(dl_se);
762762
struct rq *rq = rq_of_dl_rq(dl_rq);
763763

764+
update_rq_clock(rq);
765+
764766
WARN_ON(is_dl_boosted(dl_se));
765767
WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline));
766768

@@ -1585,23 +1587,7 @@ void dl_server_start(struct sched_dl_entity *dl_se)
15851587
{
15861588
struct rq *rq = dl_se->rq;
15871589

1588-
/*
1589-
* XXX: the apply do not work fine at the init phase for the
1590-
* fair server because things are not yet set. We need to improve
1591-
* this before getting generic.
1592-
*/
1593-
if (!dl_server(dl_se)) {
1594-
u64 runtime = 50 * NSEC_PER_MSEC;
1595-
u64 period = 1000 * NSEC_PER_MSEC;
1596-
1597-
dl_server_apply_params(dl_se, runtime, period, 1);
1598-
1599-
dl_se->dl_server = 1;
1600-
dl_se->dl_defer = 1;
1601-
setup_new_dl_entity(dl_se);
1602-
}
1603-
1604-
if (!dl_se->dl_runtime || dl_se->dl_server_active)
1590+
if (!dl_server(dl_se) || dl_se->dl_server_active)
16051591
return;
16061592

16071593
dl_se->dl_server_active = 1;
@@ -1612,7 +1598,7 @@ void dl_server_start(struct sched_dl_entity *dl_se)
16121598

16131599
void dl_server_stop(struct sched_dl_entity *dl_se)
16141600
{
1615-
if (!dl_se->dl_runtime)
1601+
if (!dl_server(dl_se) || !dl_server_active(dl_se))
16161602
return;
16171603

16181604
dequeue_dl_entity(dl_se, DEQUEUE_SLEEP);
@@ -1645,6 +1631,32 @@ void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq,
16451631
dl_se->server_pick_task = pick_task;
16461632
}
16471633

1634+
void sched_init_dl_servers(void)
1635+
{
1636+
int cpu;
1637+
struct rq *rq;
1638+
struct sched_dl_entity *dl_se;
1639+
1640+
for_each_online_cpu(cpu) {
1641+
u64 runtime = 50 * NSEC_PER_MSEC;
1642+
u64 period = 1000 * NSEC_PER_MSEC;
1643+
1644+
rq = cpu_rq(cpu);
1645+
1646+
guard(rq_lock_irq)(rq);
1647+
1648+
dl_se = &rq->fair_server;
1649+
1650+
WARN_ON(dl_server(dl_se));
1651+
1652+
dl_server_apply_params(dl_se, runtime, period, 1);
1653+
1654+
dl_se->dl_server = 1;
1655+
dl_se->dl_defer = 1;
1656+
setup_new_dl_entity(dl_se);
1657+
}
1658+
}
1659+
16481660
void __dl_server_attach_root(struct sched_dl_entity *dl_se, struct rq *rq)
16491661
{
16501662
u64 new_bw = dl_se->dl_bw;

kernel/sched/sched.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ extern void dl_server_stop(struct sched_dl_entity *dl_se);
385385
extern void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq,
386386
dl_server_has_tasks_f has_tasks,
387387
dl_server_pick_f pick_task);
388+
extern void sched_init_dl_servers(void);
388389

389390
extern void dl_server_update_idle_time(struct rq *rq,
390391
struct task_struct *p);

0 commit comments

Comments
 (0)