Re: [PATCH] rcu: Delay the RCU-selftests during boot.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Mar 01, 2022 at 06:43:01PM +0100, Sebastian Andrzej Siewior wrote:
> 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.

No offense taken.

There have been several different things requiring various pieces of RCU
to be running quite early, and I need to do a bit of code archaeology to
check this out.  One of these is what forced me to move to expedited grace
periods once the scheduler started.  And the expedited grace periods do
require the timers be working, at least in their current form.

I vaguely recall tracing requiring call_rcu() extremely early (as
in before rcu_init() is called), but that was not a problem because
there was no requirement that the callback be invoked before the first
couple of sets of initcalls had completed.  The only challenge in this
case was to avoid stomping on the callback lists at rcu_init() time,
no timers required.

One straightforward approach would be to choose the call site of the
rcu_tasks_initiate_self_tests() function based on whether or not the
kernel was built with CONFIG_PREEMPT_RT.

The other thought that comes to mind is that you may need the old-style
softirq until ksoftirqd is spawned.  I doubt that real-time response is
a big deal that early in boot.  ;-)

							Thanx, Paul

>  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
> 



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux