rcutorture: Suppress forward-progress complaints during early boot
authorPaul E. McKenney <paulmck@kernel.org>
Fri, 29 Nov 2019 02:54:06 +0000 (18:54 -0800)
committerPaul E. McKenney <paulmck@kernel.org>
Fri, 21 Feb 2020 00:03:30 +0000 (16:03 -0800)
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 <paulmck@kernel.org>
[ 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 <bp@alien8.de>
include/linux/rcutiny.h
include/linux/rcutree.h
kernel/rcu/rcutorture.c
kernel/rcu/tree_exp.h
kernel/rcu/update.c

index b2b2dc990da99b7cb0191a6c380dffccc0b58c3e..045c28b71f4f3bd8a5250395d0fdd3fb232244cd 100644 (file)
@@ -83,6 +83,7 @@ void rcu_scheduler_starting(void);
 static inline void rcu_scheduler_starting(void) { }
 #endif /* #else #ifndef CONFIG_SRCU */
 static inline void rcu_end_inkernel_boot(void) { }
+static inline bool rcu_inkernel_boot_has_ended(void) { return true; }
 static inline bool rcu_is_watching(void) { return true; }
 static inline void rcu_momentary_dyntick_idle(void) { }
 static inline void kfree_rcu_scheduler_running(void) { }
index 2f787b9029d1ed0770da54db6d1a6b0ae89d7849..45f3f66bb04df719f6e8350ab07bd33301ac070a 100644 (file)
@@ -54,6 +54,7 @@ void exit_rcu(void);
 void rcu_scheduler_starting(void);
 extern int rcu_scheduler_active __read_mostly;
 void rcu_end_inkernel_boot(void);
+bool rcu_inkernel_boot_has_ended(void);
 bool rcu_is_watching(void);
 #ifndef CONFIG_PREEMPTION
 void rcu_all_qs(void);
index 1aeecc165b2168b697f1410d8f4f38b79e755ec6..9ba49788cb48fff93e443e5989e6621a05dd772f 100644 (file)
@@ -1067,7 +1067,8 @@ rcu_torture_writer(void *arg)
                if (stutter_wait("rcu_torture_writer") &&
                    !READ_ONCE(rcu_fwd_cb_nodelay) &&
                    !cur_ops->slow_gps &&
-                   !torture_must_stop())
+                   !torture_must_stop() &&
+                   rcu_inkernel_boot_has_ended())
                        for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++)
                                if (list_empty(&rcu_tortures[i].rtort_free) &&
                                    rcu_access_pointer(rcu_torture_current) !=
index dcbd75791f3926f815391ff45406e53c3bfb0ef4..a72d16eb869eed5fd2dff0cf16431d3991954014 100644 (file)
@@ -485,6 +485,7 @@ static bool synchronize_rcu_expedited_wait_once(long tlimit)
 static void synchronize_rcu_expedited_wait(void)
 {
        int cpu;
+       unsigned long j;
        unsigned long jiffies_stall;
        unsigned long jiffies_start;
        unsigned long mask;
@@ -496,7 +497,7 @@ static void synchronize_rcu_expedited_wait(void)
        trace_rcu_exp_grace_period(rcu_state.name, rcu_exp_gp_seq_endval(), TPS("startwait"));
        jiffies_stall = rcu_jiffies_till_stall_check();
        jiffies_start = jiffies;
-       if (IS_ENABLED(CONFIG_NO_HZ_FULL)) {
+       if (tick_nohz_full_enabled() && rcu_inkernel_boot_has_ended()) {
                if (synchronize_rcu_expedited_wait_once(1))
                        return;
                rcu_for_each_leaf_node(rnp) {
@@ -508,6 +509,10 @@ static void synchronize_rcu_expedited_wait(void)
                                tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
                        }
                }
+               j = READ_ONCE(jiffies_till_first_fqs);
+               if (synchronize_rcu_expedited_wait_once(j + HZ))
+                       return;
+               WARN_ON_ONCE(IS_ENABLED(CONFIG_PREEMPT_RT));
        }
 
        for (;;) {
index 6c4b862f57d6fc0620e6a24f857cb9c1a54ce2d4..feaaec5747a34f5a83b51dd403e43978b260e267 100644 (file)
@@ -183,6 +183,8 @@ void rcu_unexpedite_gp(void)
 }
 EXPORT_SYMBOL_GPL(rcu_unexpedite_gp);
 
+static bool rcu_boot_ended __read_mostly;
+
 /*
  * Inform RCU of the end of the in-kernel boot sequence.
  */
@@ -191,7 +193,17 @@ void rcu_end_inkernel_boot(void)
        rcu_unexpedite_gp();
        if (rcu_normal_after_boot)
                WRITE_ONCE(rcu_normal, 1);
+       rcu_boot_ended = 1;
+}
+
+/*
+ * Let rcutorture know when it is OK to turn it up to eleven.
+ */
+bool rcu_inkernel_boot_has_ended(void)
+{
+       return rcu_boot_ended;
 }
+EXPORT_SYMBOL_GPL(rcu_inkernel_boot_has_ended);
 
 #endif /* #ifndef CONFIG_TINY_RCU */