From 8969e435d44ace820c46c7540cc66e68e62b1249 Mon Sep 17 00:00:00 2001 From: Oleksii Moisieiev Date: Fri, 22 May 2026 08:14:48 +0200 Subject: [PATCH] xen/sched: rtds: assert replq is empty on timer (re-)init In RTDS, removing the last eligible pCPU kills repl_timer. When a pCPU is later re-added, rt_switch_sched() reinitializes the timer object. cpupool_unassign_cpu_start() refuses to remove the last pCPU from a populated cpupool: if any domain is still alive while the system is active it returns -EBUSY, otherwise all domains are first moved to cpupool0. Consequently, by the time the killed-timer branch runs, no units remain in the pool and replq is guaranteed to be empty. Document this invariant by asserting list_empty(replq) right after init_timer(). This catches any future regression in cpupool semantics that would leave pending replenishment events behind across a TIMER_STATUS_killed -> init_timer() transition, where the timer would otherwise stay disarmed until an unrelated event reprogrammed it. Signed-off-by: Oleksii Moisieiev Reviewed-by: Juergen Gross Acked-by: Jan Beulich --- xen/common/sched/rt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xen/common/sched/rt.c b/xen/common/sched/rt.c index 6109aa66c2..4b637aa9db 100644 --- a/xen/common/sched/rt.c +++ b/xen/common/sched/rt.c @@ -749,6 +749,14 @@ rt_switch_sched(struct scheduler *new_ops, unsigned int cpu, { init_timer(&prv->repl_timer, repl_timer_handler, (void *)new_ops, cpu); dprintk(XENLOG_DEBUG, "RTDS: timer initialized on cpu %u\n", cpu); + + /* + * cpupool_unassign_cpu_start() refuses to remove the last pCPU from + * a populated cpupool, so by the time this path runs (timer was + * killed because all RTDS pCPUs were removed) the pool must have + * been empty of domains, which implies replq is empty too. + */ + ASSERT(list_empty(rt_replq(new_ops))); } sched_idle_unit(cpu)->priv = vdata;