Skip to content

Commit 59ee032

Browse files
committed
rcutorture: Suppress forward-progress complaints during early boot
Some larger systems can take in excess of 50 seconds to complete their early boot initcalls prior to spawing init. This does not in any way help the forward-progress judgments of built-in rcutorture (when rcutorture is built as a module, the insmod or modprobe command normally cannot happen until some time after boot completes). This commit therefore suppresses such complaints until about the time that init is spawned. This also includes a fix to a stupid error located by kbuild test robot. [ paulmck: Apply kbuild test robot feedback. ] Signed-off-by: Paul E. McKenney <[email protected]> [ paulmck: Fix to nohz_full slow-expediting recovery logic, per bpetkov. ] [ paulmck: Restrict splat to CONFIG_PREEMPT_RT=y kernels and simplify. ] Tested-by: Borislav Petkov <[email protected]>
1 parent bb6d3fb commit 59ee032

File tree

5 files changed

+22
-2
lines changed

5 files changed

+22
-2
lines changed

include/linux/rcutiny.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void rcu_scheduler_starting(void);
8383
static inline void rcu_scheduler_starting(void) { }
8484
#endif /* #else #ifndef CONFIG_SRCU */
8585
static inline void rcu_end_inkernel_boot(void) { }
86+
static inline bool rcu_inkernel_boot_has_ended(void) { return true; }
8687
static inline bool rcu_is_watching(void) { return true; }
8788
static inline void rcu_momentary_dyntick_idle(void) { }
8889
static inline void kfree_rcu_scheduler_running(void) { }

include/linux/rcutree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void exit_rcu(void);
5454
void rcu_scheduler_starting(void);
5555
extern int rcu_scheduler_active __read_mostly;
5656
void rcu_end_inkernel_boot(void);
57+
bool rcu_inkernel_boot_has_ended(void);
5758
bool rcu_is_watching(void);
5859
#ifndef CONFIG_PREEMPTION
5960
void rcu_all_qs(void);

kernel/rcu/rcutorture.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,8 @@ rcu_torture_writer(void *arg)
10671067
if (stutter_wait("rcu_torture_writer") &&
10681068
!READ_ONCE(rcu_fwd_cb_nodelay) &&
10691069
!cur_ops->slow_gps &&
1070-
!torture_must_stop())
1070+
!torture_must_stop() &&
1071+
rcu_inkernel_boot_has_ended())
10711072
for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++)
10721073
if (list_empty(&rcu_tortures[i].rtort_free) &&
10731074
rcu_access_pointer(rcu_torture_current) !=

kernel/rcu/tree_exp.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ static bool synchronize_rcu_expedited_wait_once(long tlimit)
485485
static void synchronize_rcu_expedited_wait(void)
486486
{
487487
int cpu;
488+
unsigned long j;
488489
unsigned long jiffies_stall;
489490
unsigned long jiffies_start;
490491
unsigned long mask;
@@ -496,7 +497,7 @@ static void synchronize_rcu_expedited_wait(void)
496497
trace_rcu_exp_grace_period(rcu_state.name, rcu_exp_gp_seq_endval(), TPS("startwait"));
497498
jiffies_stall = rcu_jiffies_till_stall_check();
498499
jiffies_start = jiffies;
499-
if (IS_ENABLED(CONFIG_NO_HZ_FULL)) {
500+
if (tick_nohz_full_enabled() && rcu_inkernel_boot_has_ended()) {
500501
if (synchronize_rcu_expedited_wait_once(1))
501502
return;
502503
rcu_for_each_leaf_node(rnp) {
@@ -508,6 +509,10 @@ static void synchronize_rcu_expedited_wait(void)
508509
tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
509510
}
510511
}
512+
j = READ_ONCE(jiffies_till_first_fqs);
513+
if (synchronize_rcu_expedited_wait_once(j + HZ))
514+
return;
515+
WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_RT));
511516
}
512517

513518
for (;;) {

kernel/rcu/update.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ void rcu_unexpedite_gp(void)
183183
}
184184
EXPORT_SYMBOL_GPL(rcu_unexpedite_gp);
185185

186+
static bool rcu_boot_ended __read_mostly;
187+
186188
/*
187189
* Inform RCU of the end of the in-kernel boot sequence.
188190
*/
@@ -191,7 +193,17 @@ void rcu_end_inkernel_boot(void)
191193
rcu_unexpedite_gp();
192194
if (rcu_normal_after_boot)
193195
WRITE_ONCE(rcu_normal, 1);
196+
rcu_boot_ended = 1;
197+
}
198+
199+
/*
200+
* Let rcutorture know when it is OK to turn it up to eleven.
201+
*/
202+
bool rcu_inkernel_boot_has_ended(void)
203+
{
204+
return rcu_boot_ended;
194205
}
206+
EXPORT_SYMBOL_GPL(rcu_inkernel_boot_has_ended);
195207

196208
#endif /* #ifndef CONFIG_TINY_RCU */
197209

0 commit comments

Comments
 (0)