Message ID | 20220614120620.1202389-1-longman@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [PATCH-rcu] rcu-tasks: Use delayed_work to delay rcu_tasks_verify_self_tests() | expand |
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@redhat.com> 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 >
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 */
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@redhat.com> --- kernel/rcu/tasks.h | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-)