rcu: Make SRCU mandatory
authorPaul E. McKenney <paulmck@kernel.org>
Tue, 22 Nov 2022 21:53:57 +0000 (13:53 -0800)
committerPaul E. McKenney <paulmck@kernel.org>
Tue, 29 Nov 2022 23:00:06 +0000 (15:00 -0800)
Kernels configured with CONFIG_PRINTK=n and CONFIG_SRCU=n get build
failures.  This causes trouble for deep embedded systems.  But given
that there are more than 25 instances of "select SRCU" in the kernel,
it is hard to believe that there are many kernels running in production
without SRCU.  This commit therefore makes SRCU mandatory.  The SRCU
Kconfig option remains for backwards compatibility, and will be removed
when it is no longer used.

[ paulmck: Update per kernel test robot feedback. ]

Reported-by: John Ogness <john.ogness@linutronix.de>
Reported-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: <linux-arch@vger.kernel.org>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: John Ogness <john.ogness@linutronix.de>
include/linux/rcutiny.h
include/linux/srcu.h
kernel/rcu/Kconfig
kernel/rcu/Kconfig.debug
kernel/rcu/rcu.h
kernel/rcu/update.c

index 768196a5f39d695b434ae8c92f5a9665f63fc746..d40b21ec7e0da0f19e0b38f7891e0af4a23409a2 100644 (file)
@@ -154,11 +154,7 @@ static inline bool rcu_preempt_need_deferred_qs(struct task_struct *t)
        return false;
 }
 static inline void rcu_preempt_deferred_qs(struct task_struct *t) { }
-#ifdef CONFIG_SRCU
 void rcu_scheduler_starting(void);
-#else /* #ifndef CONFIG_SRCU */
-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; }
index f0814ffca34bbba4497ad17e5a7724c43d669b13..9b9d0bbf1d3cf68ade40ad4887ccc86f8a38054a 100644 (file)
@@ -47,11 +47,8 @@ int init_srcu_struct(struct srcu_struct *ssp);
 #include <linux/srcutiny.h>
 #elif defined(CONFIG_TREE_SRCU)
 #include <linux/srcutree.h>
-#elif defined(CONFIG_SRCU)
-#error "Unknown SRCU implementation specified to kernel configuration"
 #else
-/* Dummy definition for things like notifiers.  Actual use gets link error. */
-struct srcu_struct { };
+#error "Unknown SRCU implementation specified to kernel configuration"
 #endif
 
 void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
@@ -78,11 +75,7 @@ static inline void __srcu_read_unlock_nmisafe(struct srcu_struct *ssp, int idx)
 }
 #endif /* CONFIG_NEED_SRCU_NMI_SAFE */
 
-#ifdef CONFIG_SRCU
 void srcu_init(void);
-#else /* #ifdef CONFIG_SRCU */
-static inline void srcu_init(void) { }
-#endif /* #else #ifdef CONFIG_SRCU */
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
index f53ad63b2bc631ca2e614fd4ae3cfbaa5849f121..1b0d79b2f5fa0859f9289b84fcd3e96c9507bf80 100644 (file)
@@ -54,21 +54,17 @@ config RCU_EXPERT
          Say N if you are unsure.
 
 config SRCU
-       bool
-       help
-         This option selects the sleepable version of RCU. This version
-         permits arbitrary sleeping or blocking within RCU read-side critical
-         sections.
+       def_bool y
 
 config TINY_SRCU
        bool
-       default y if SRCU && TINY_RCU
+       default y if TINY_RCU
        help
          This option selects the single-CPU non-preemptible version of SRCU.
 
 config TREE_SRCU
        bool
-       default y if SRCU && !TINY_RCU
+       default y if !TINY_RCU
        help
          This option selects the full-fledged version of SRCU.
 
@@ -77,7 +73,6 @@ config NEED_SRCU_NMI_SAFE
 
 config TASKS_RCU_GENERIC
        def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
-       select SRCU
        help
          This option enables generic infrastructure code supporting
          task-based RCU implementations.  Not for manual selection.
index 1b0c41d490f0588760a459dee826a393d74d71f3..232e29fe3e5ecb8090813a32d22de6e313e9de57 100644 (file)
@@ -27,7 +27,6 @@ config RCU_SCALE_TEST
        tristate "performance tests for RCU"
        depends on DEBUG_KERNEL
        select TORTURE_TEST
-       select SRCU
        default n
        help
          This option provides a kernel module that runs performance
@@ -43,7 +42,6 @@ config RCU_TORTURE_TEST
        tristate "torture tests for RCU"
        depends on DEBUG_KERNEL
        select TORTURE_TEST
-       select SRCU
        default n
        help
          This option provides a kernel module that runs torture tests
@@ -59,7 +57,6 @@ config RCU_REF_SCALE_TEST
        tristate "Scalability tests for read-side synchronization (RCU and others)"
        depends on DEBUG_KERNEL
        select TORTURE_TEST
-       select SRCU
        default n
        help
          This option provides a kernel module that runs performance tests
index be5979da07f59850afafa5ce481141c7efd7fe40..1f7ca484483a1c7a7b7e272ec6b920d936ec5e96 100644 (file)
@@ -286,7 +286,7 @@ void rcu_test_sync_prims(void);
  */
 extern void resched_cpu(int cpu);
 
-#if defined(CONFIG_SRCU) || !defined(CONFIG_TINY_RCU)
+#if !defined(CONFIG_TINY_RCU)
 
 #include <linux/rcu_node_tree.h>
 
@@ -375,6 +375,10 @@ extern void rcu_init_geometry(void);
             (cpu) <= rnp->grphi; \
             (cpu) = rcu_find_next_bit((rnp), (cpu) + 1 - (rnp->grplo), (mask)))
 
+#endif /* !defined(CONFIG_TINY_RCU) */
+
+#if !defined(CONFIG_TINY_RCU) || defined(CONFIG_TASKS_RCU_GENERIC)
+
 /*
  * Wrappers for the rcu_node::lock acquire and release.
  *
@@ -437,7 +441,7 @@ do {                                                                        \
 #define raw_lockdep_assert_held_rcu_node(p)                            \
        lockdep_assert_held(&ACCESS_PRIVATE(p, lock))
 
-#endif /* #if defined(CONFIG_SRCU) || !defined(CONFIG_TINY_RCU) */
+#endif // #if !defined(CONFIG_TINY_RCU) || defined(CONFIG_TASKS_RCU_GENERIC)
 
 #ifdef CONFIG_TINY_RCU
 /* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */
index 738842c4886b235702e402d7390600287290375f..f5e6a2f95a2a0b00dad748219b1c9c5bbb64c68f 100644 (file)
@@ -224,7 +224,7 @@ void rcu_test_sync_prims(void)
        synchronize_rcu_expedited();
 }
 
-#if !defined(CONFIG_TINY_RCU) || defined(CONFIG_SRCU)
+#if !defined(CONFIG_TINY_RCU)
 
 /*
  * Switch to run-time mode once RCU has fully initialized.
@@ -239,7 +239,7 @@ static int __init rcu_set_runtime_mode(void)
 }
 core_initcall(rcu_set_runtime_mode);
 
-#endif /* #if !defined(CONFIG_TINY_RCU) || defined(CONFIG_SRCU) */
+#endif /* #if !defined(CONFIG_TINY_RCU) */
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key rcu_lock_key;
@@ -559,10 +559,8 @@ static void early_boot_test_call_rcu(void)
        struct early_boot_kfree_rcu *rhp;
 
        call_rcu(&head, test_callback);
-       if (IS_ENABLED(CONFIG_SRCU)) {
-               early_srcu_cookie = start_poll_synchronize_srcu(&early_srcu);
-               call_srcu(&early_srcu, &shead, test_callback);
-       }
+       early_srcu_cookie = start_poll_synchronize_srcu(&early_srcu);
+       call_srcu(&early_srcu, &shead, test_callback);
        rhp = kmalloc(sizeof(*rhp), GFP_KERNEL);
        if (!WARN_ON_ONCE(!rhp))
                kfree_rcu(rhp, rh);
@@ -585,11 +583,9 @@ static int rcu_verify_early_boot_tests(void)
        if (rcu_self_test) {
                early_boot_test_counter++;
                rcu_barrier();
-               if (IS_ENABLED(CONFIG_SRCU)) {
-                       early_boot_test_counter++;
-                       srcu_barrier(&early_srcu);
-                       WARN_ON_ONCE(!poll_state_synchronize_srcu(&early_srcu, early_srcu_cookie));
-               }
+               early_boot_test_counter++;
+               srcu_barrier(&early_srcu);
+               WARN_ON_ONCE(!poll_state_synchronize_srcu(&early_srcu, early_srcu_cookie));
        }
        if (rcu_self_test_counter != early_boot_test_counter) {
                WARN_ON(1);