On Tue, Jun 14, 2022 at 08:06:20AM -0400, Waiman Long wrote: > Commit 2585014188d5 ("rcu-tasks: Be more patient for RCU Tasks > boot-time testing") fixes false positive rcu_tasks verification check > failure by repeating the test once every second until timeout using > schedule_timeout_uninterruptible(). > > Since rcu_tasks_verify_selft_tests() is called from do_initcalls() > as a late_initcall, this has the undesirable side effect of perhaps > delaying other late_initcall's queued after it by a second or more. > Fix this by using delayed_work to repeat the verification check instead. > > Fixes: 2585014188d5 ("rcu-tasks: Be more patient for RCU Tasks boot-time testing") > Signed-off-by: Waiman Long <longman@xxxxxxxxxx> Applied, thank you! Thanx, Paul > --- > kernel/rcu/tasks.h | 35 ++++++++++++++++++++++++++++++++--- > 1 file changed, 32 insertions(+), 3 deletions(-) > > diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h > index fcbd0ec33c86..e151cd5ae2bc 100644 > --- a/kernel/rcu/tasks.h > +++ b/kernel/rcu/tasks.h > @@ -1832,6 +1832,11 @@ static void rcu_tasks_initiate_self_tests(void) > #endif > } > > +/* > + * Return: 0 - test passed > + * 1 - test failed, but have not timed out yet > + * -1 - test failed and timed out > + */ > static int rcu_tasks_verify_self_tests(void) > { > int ret = 0; > @@ -1847,16 +1852,40 @@ static int rcu_tasks_verify_self_tests(void) > ret = -1; > break; > } > - schedule_timeout_uninterruptible(1); > + ret = 1; > + break; > } > } > > - if (ret) > + if (ret < 0) > WARN_ON(1); > > return ret; > } > -late_initcall(rcu_tasks_verify_self_tests); > + > +/* > + * Repeat the rcu_tasks_verify_self_tests() call once every second until the > + * test passes or has timed out. > + */ > +static struct delayed_work rcu_tasks_verify_work; > +static void rcu_tasks_verify_work_fn(struct work_struct *work __maybe_unused) > +{ > + int ret = rcu_tasks_verify_self_tests(); > + > + if (ret <= 0) > + return; > + > + /* Test fails but not timed out yet, reschedule another check */ > + schedule_delayed_work(&rcu_tasks_verify_work, HZ); > +} > + > +static int rcu_tasks_verify_schedule_work(void) > +{ > + INIT_DELAYED_WORK(&rcu_tasks_verify_work, rcu_tasks_verify_work_fn); > + rcu_tasks_verify_work_fn(NULL); > + return 0; > +} > +late_initcall(rcu_tasks_verify_schedule_work); > #else /* #ifdef CONFIG_PROVE_RCU */ > static void rcu_tasks_initiate_self_tests(void) { } > #endif /* #else #ifdef CONFIG_PROVE_RCU */ > -- > 2.31.1 >