Skip to content

Commit 79d9330

Browse files
committed
sched/deadline: Initialize dl_servers after SMP
JIRA: https://issues.redhat.com/browse/RHEL-105980 commit 9f239df Author: Juri Lelli <juri.lelli@redhat.com> Date: Fri Jun 27 13:51:14 2025 +0200 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 <marcel.ziswiler@codethink.co.uk> Signed-off-by: Juri Lelli <juri.lelli@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Waiman Long <longman@redhat.com> Tested-by: Marcel Ziswiler <marcel.ziswiler@codethink.co.uk> # nuc & rock5b Link: https://lore.kernel.org/r/20250627115118.438797-2-juri.lelli@redhat.com Signed-off-by: Phil Auld <pauld@redhat.com>
1 parent 1b37f47 commit 79d9330

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
@@ -8510,6 +8510,8 @@ void __init sched_init_smp(void)
85108510
init_sched_rt_class();
85118511
init_sched_dl_class();
85128512

8513+
sched_init_dl_servers();
8514+
85138515
sched_smp_initialized = true;
85148516
}
85158517

kernel/sched/deadline.c

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

827+
update_rq_clock(rq);
828+
827829
WARN_ON(is_dl_boosted(dl_se));
828830
WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline));
829831

@@ -1653,23 +1655,7 @@ void dl_server_start(struct sched_dl_entity *dl_se)
16531655
{
16541656
struct rq *rq = dl_se->rq;
16551657

1656-
/*
1657-
* XXX: the apply do not work fine at the init phase for the
1658-
* fair server because things are not yet set. We need to improve
1659-
* this before getting generic.
1660-
*/
1661-
if (!dl_server(dl_se)) {
1662-
u64 runtime = 50 * NSEC_PER_MSEC;
1663-
u64 period = 1000 * NSEC_PER_MSEC;
1664-
1665-
dl_server_apply_params(dl_se, runtime, period, 1);
1666-
1667-
dl_se->dl_server = 1;
1668-
dl_se->dl_defer = 1;
1669-
setup_new_dl_entity(dl_se);
1670-
}
1671-
1672-
if (!dl_se->dl_runtime || dl_se->dl_server_active)
1658+
if (!dl_server(dl_se) || dl_se->dl_server_active)
16731659
return;
16741660

16751661
dl_se->dl_server_active = 1;
@@ -1680,7 +1666,7 @@ void dl_server_start(struct sched_dl_entity *dl_se)
16801666

16811667
void dl_server_stop(struct sched_dl_entity *dl_se)
16821668
{
1683-
if (!dl_se->dl_runtime)
1669+
if (!dl_server(dl_se) || !dl_server_active(dl_se))
16841670
return;
16851671

16861672
dequeue_dl_entity(dl_se, DEQUEUE_SLEEP);
@@ -1713,6 +1699,32 @@ void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq,
17131699
dl_se->server_pick_task = pick_task;
17141700
}
17151701

1702+
void sched_init_dl_servers(void)
1703+
{
1704+
int cpu;
1705+
struct rq *rq;
1706+
struct sched_dl_entity *dl_se;
1707+
1708+
for_each_online_cpu(cpu) {
1709+
u64 runtime = 50 * NSEC_PER_MSEC;
1710+
u64 period = 1000 * NSEC_PER_MSEC;
1711+
1712+
rq = cpu_rq(cpu);
1713+
1714+
guard(rq_lock_irq)(rq);
1715+
1716+
dl_se = &rq->fair_server;
1717+
1718+
WARN_ON(dl_server(dl_se));
1719+
1720+
dl_server_apply_params(dl_se, runtime, period, 1);
1721+
1722+
dl_se->dl_server = 1;
1723+
dl_se->dl_defer = 1;
1724+
setup_new_dl_entity(dl_se);
1725+
}
1726+
}
1727+
17161728
void __dl_server_attach_root(struct sched_dl_entity *dl_se, struct rq *rq)
17171729
{
17181730
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
@@ -390,6 +390,7 @@ extern void dl_server_stop(struct sched_dl_entity *dl_se);
390390
extern void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq,
391391
dl_server_has_tasks_f has_tasks,
392392
dl_server_pick_f pick_task);
393+
extern void sched_init_dl_servers(void);
393394

394395
extern void dl_server_update_idle_time(struct rq *rq,
395396
struct task_struct *p);

0 commit comments

Comments
 (0)