The RCU-sefltest expects tthe timer_list timer to be working. This isn't the case on PREEMPT_RT at this point because it requires that ksoftirqd is up and running. There is no known requirement that synchronize_rcu() works at this point. Delay RCU-selftests until ksoftirqd is up and running. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> --- Paul, I don't mean to be rude or anything by saying that "There is no requirement…". If my memory serves me well here (and there is no guarantee for that) then synchronize_rcu() was required that early by kprobes or jump labels and this requirement was lifted by the time we discussed this. I have no idea how this discussion back then ended but as of v5.17-rc6 that timer is still required to function in order for the system to make progress at boot time. include/linux/rcupdate.h | 6 ++++++ init/main.c | 1 + kernel/rcu/tasks.h | 10 +++------- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 88b42eb464068..2fb1a48ca9272 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -95,6 +95,12 @@ void rcu_init_tasks_generic(void); static inline void rcu_init_tasks_generic(void) { } #endif +#if defined(CONFIG_PROVE_RCU) && defined(CONFIG_TASKS_RCU_GENERIC) +void rcu_tasks_initiate_self_tests(void); +#else +static inline void rcu_tasks_initiate_self_tests(void) {} +#endif + #ifdef CONFIG_RCU_STALL_COMMON void rcu_sysrq_start(void); void rcu_sysrq_end(void); diff --git a/init/main.c b/init/main.c index 65fa2e41a9c09..cfc45e47b9ca4 100644 --- a/init/main.c +++ b/init/main.c @@ -1600,6 +1600,7 @@ static noinline void __init kernel_init_freeable(void) rcu_init_tasks_generic(); do_pre_smp_initcalls(); + rcu_tasks_initiate_self_tests(); lockup_detector_init(); smp_init(); diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index d64f0b1d8cd3b..215c2c0f6c184 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -1659,9 +1659,10 @@ static void test_rcu_tasks_callback(struct rcu_head *rhp) pr_info("Callback from %s invoked.\n", rttd->name); rttd->notrun = true; + WARN_ON(1); } -static void rcu_tasks_initiate_self_tests(void) +void rcu_tasks_initiate_self_tests(void) { pr_info("Running RCU-tasks wait API self tests\n"); #ifdef CONFIG_TASKS_RCU @@ -1698,9 +1699,7 @@ static int rcu_tasks_verify_self_tests(void) return ret; } late_initcall(rcu_tasks_verify_self_tests); -#else /* #ifdef CONFIG_PROVE_RCU */ -static void rcu_tasks_initiate_self_tests(void) { } -#endif /* #else #ifdef CONFIG_PROVE_RCU */ +#endif /* #ifdef CONFIG_PROVE_RCU */ void __init rcu_init_tasks_generic(void) { @@ -1715,9 +1714,6 @@ void __init rcu_init_tasks_generic(void) #ifdef CONFIG_TASKS_TRACE_RCU rcu_spawn_tasks_trace_kthread(); #endif - - // Run the self-tests. - rcu_tasks_initiate_self_tests(); } #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */ -- 2.35.1