Sometimes, the kernel will boot too fast for rcu_tasks_verify_self_tests to have all required grace periods. Temporarily reduce rcu tasks kthread sleep time for PROVE_RCU to get all required grace periods. Both this patch and her sister "wait extra jiffies for rcu_tasks_verify_self_tests" https://lore.kernel.org/rcu/20220517004522.25176-1-zhouzhouyi@xxxxxxxxx/ have their short comings: 1) this patch don't slow down the Linux boot time but will increase the energe consumption during the boot because of reduced sleep time. 2) "wait extra jiffies for rcu_tasks_verify_self_tests" may slow the boot process but has not energe problems. Reported-by: Matthew Wilcox <willy@xxxxxxxxxxxxx> Suggested-by: Paul E. McKenney <paulmck@xxxxxxxxxx> Tested-by: Zhouyi Zhou <zhouzhouyi@xxxxxxxxx> Signed-off-by: Zhouyi Zhou <zhouzhouyi@xxxxxxxxx> --- Hi Paul I have proposed some possible solutions to fix rcu_tasks_verify_self_tests failure. Both of them are not perfect. Only tries to break the ice, hoping to arouse the attension ;-) Thanks Zhouyi -- kernel/rcu/tasks.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 6ed21720b13f..f7c849ef23fa 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -962,3 +962,10 @@ EXPORT_SYMBOL_GPL(rcu_barrier_tasks); static int __init rcu_spawn_tasks_kthread(void) { cblist_init_generic(&rcu_tasks); +#ifdef CONFIG_PROVE_RCU + /* temporarily reduce rcu tasks kthread sleep time for the kernel + * that boot faster + */ + rcu_tasks.gp_sleep = HZ / 200; + rcu_tasks.init_fract = HZ / 200; +#else rcu_tasks.gp_sleep = HZ / 10; rcu_tasks.init_fract = HZ / 10; +#endif rcu_tasks.pregp_func = rcu_tasks_pregp_step; rcu_tasks.pertask_func = rcu_tasks_pertask; rcu_tasks.postscan_func = rcu_tasks_postscan; @@ -1103,7 +1111,14 @@ EXPORT_SYMBOL_GPL(rcu_barrier_tasks_rude); static int __init rcu_spawn_tasks_rude_kthread(void) { cblist_init_generic(&rcu_tasks_rude); +#ifdef CONFIG_PROVE_RCU + /* temporarily reduce rcu tasks rude kthread sleep time for the kernel + * that boot faster + */ + rcu_tasks_rude.gp_sleep = HZ / 200; +#else rcu_tasks_rude.gp_sleep = HZ / 10; +#endif rcu_spawn_tasks_kthread_generic(&rcu_tasks_rude); return 0; } @@ -1665,3 +1680,14 @@ static int __init rcu_spawn_tasks_trace_kthread(void) { cblist_init_generic(&rcu_tasks_trace); if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) { +#ifdef CONFIG_PROVE_RCU + /* temporarily reduce rcu tasks trace kthread sleep + * time for the kernel that boot faster + */ + rcu_tasks_trace.gp_sleep = HZ / 200; + if (rcu_tasks_trace.gp_sleep <= 0) + rcu_tasks_trace.gp_sleep = 1; + rcu_tasks_trace.init_fract = HZ / 200; + if (rcu_tasks_trace.init_fract <= 0) + rcu_tasks_trace.init_fract = 1; +#else rcu_tasks_trace.gp_sleep = HZ / 10; rcu_tasks_trace.init_fract = HZ / 10; +#endif } else { rcu_tasks_trace.gp_sleep = HZ / 200; if (rcu_tasks_trace.gp_sleep <= 0) @@ -1777,3 +1804,20 @@ static int rcu_tasks_verify_self_tests(void) } } +/* resume rcu tasks kthreads' sleep time after self tests */ +#ifdef CONFIG_TASKS_RCU + rcu_tasks.gp_sleep = HZ / 10; + rcu_tasks.init_fract = HZ / 10; +#endif + +#ifdef CONFIG_TASKS_RUDE_RCU + rcu_tasks_rude.gp_sleep = HZ / 10; +#endif + +#ifdef CONFIG_TASKS_TRACE_RCU + if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) { + rcu_tasks_trace.gp_sleep = HZ / 10; + rcu_tasks_trace.init_fract = HZ / 10; + } +#endif + if (ret) WARN_ON(1); -- 2.25.1