Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: d741f297bceaf ("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

authored by

Juri Lelli and committed by
Peter Zijlstra
9f239df5 2885daf4

+33 -18
+2
kernel/sched/core.c
··· 8371 8371 init_sched_rt_class(); 8372 8372 init_sched_dl_class(); 8373 8373 8374 + sched_init_dl_servers(); 8375 + 8374 8376 sched_smp_initialized = true; 8375 8377 } 8376 8378
+30 -18
kernel/sched/deadline.c
··· 761 761 struct dl_rq *dl_rq = dl_rq_of_se(dl_se); 762 762 struct rq *rq = rq_of_dl_rq(dl_rq); 763 763 764 + update_rq_clock(rq); 765 + 764 766 WARN_ON(is_dl_boosted(dl_se)); 765 767 WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline)); 766 768 ··· 1587 1585 { 1588 1586 struct rq *rq = dl_se->rq; 1589 1587 1590 - /* 1591 - * XXX: the apply do not work fine at the init phase for the 1592 - * fair server because things are not yet set. We need to improve 1593 - * this before getting generic. 1594 - */ 1595 - if (!dl_server(dl_se)) { 1596 - u64 runtime = 50 * NSEC_PER_MSEC; 1597 - u64 period = 1000 * NSEC_PER_MSEC; 1598 - 1599 - dl_server_apply_params(dl_se, runtime, period, 1); 1600 - 1601 - dl_se->dl_server = 1; 1602 - dl_se->dl_defer = 1; 1603 - setup_new_dl_entity(dl_se); 1604 - } 1605 - 1606 - if (!dl_se->dl_runtime || dl_se->dl_server_active) 1588 + if (!dl_server(dl_se) || dl_se->dl_server_active) 1607 1589 return; 1608 1590 1609 1591 dl_se->dl_server_active = 1; ··· 1598 1612 1599 1613 void dl_server_stop(struct sched_dl_entity *dl_se) 1600 1614 { 1601 - if (!dl_se->dl_runtime) 1615 + if (!dl_server(dl_se) || !dl_server_active(dl_se)) 1602 1616 return; 1603 1617 1604 1618 dequeue_dl_entity(dl_se, DEQUEUE_SLEEP); ··· 1629 1643 dl_se->rq = rq; 1630 1644 dl_se->server_has_tasks = has_tasks; 1631 1645 dl_se->server_pick_task = pick_task; 1646 + } 1647 + 1648 + void sched_init_dl_servers(void) 1649 + { 1650 + int cpu; 1651 + struct rq *rq; 1652 + struct sched_dl_entity *dl_se; 1653 + 1654 + for_each_online_cpu(cpu) { 1655 + u64 runtime = 50 * NSEC_PER_MSEC; 1656 + u64 period = 1000 * NSEC_PER_MSEC; 1657 + 1658 + rq = cpu_rq(cpu); 1659 + 1660 + guard(rq_lock_irq)(rq); 1661 + 1662 + dl_se = &rq->fair_server; 1663 + 1664 + WARN_ON(dl_server(dl_se)); 1665 + 1666 + dl_server_apply_params(dl_se, runtime, period, 1); 1667 + 1668 + dl_se->dl_server = 1; 1669 + dl_se->dl_defer = 1; 1670 + setup_new_dl_entity(dl_se); 1671 + } 1632 1672 } 1633 1673 1634 1674 void __dl_server_attach_root(struct sched_dl_entity *dl_se, struct rq *rq)
+1
kernel/sched/sched.h
··· 385 385 extern void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq, 386 386 dl_server_has_tasks_f has_tasks, 387 387 dl_server_pick_f pick_task); 388 + extern void sched_init_dl_servers(void); 388 389 389 390 extern void dl_server_update_idle_time(struct rq *rq, 390 391 struct task_struct *p);