Commit 0cd7e350 authored by Paul E. McKenney's avatar Paul E. McKenney

rcu: Make SRCU mandatory

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: default avatarJohn Ogness <john.ogness@linutronix.de>
Reported-by: default avatarPetr Mladek <pmladek@suse.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
Cc: <linux-arch@vger.kernel.org>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Reviewed-by: default avatarJohn Ogness <john.ogness@linutronix.de>
parent f733615e
...@@ -154,11 +154,7 @@ static inline bool rcu_preempt_need_deferred_qs(struct task_struct *t) ...@@ -154,11 +154,7 @@ static inline bool rcu_preempt_need_deferred_qs(struct task_struct *t)
return false; return false;
} }
static inline void rcu_preempt_deferred_qs(struct task_struct *t) { } static inline void rcu_preempt_deferred_qs(struct task_struct *t) { }
#ifdef CONFIG_SRCU
void rcu_scheduler_starting(void); 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 void rcu_end_inkernel_boot(void) { }
static inline bool rcu_inkernel_boot_has_ended(void) { return true; } static inline bool rcu_inkernel_boot_has_ended(void) { return true; }
static inline bool rcu_is_watching(void) { return true; } static inline bool rcu_is_watching(void) { return true; }
......
...@@ -47,11 +47,8 @@ int init_srcu_struct(struct srcu_struct *ssp); ...@@ -47,11 +47,8 @@ int init_srcu_struct(struct srcu_struct *ssp);
#include <linux/srcutiny.h> #include <linux/srcutiny.h>
#elif defined(CONFIG_TREE_SRCU) #elif defined(CONFIG_TREE_SRCU)
#include <linux/srcutree.h> #include <linux/srcutree.h>
#elif defined(CONFIG_SRCU)
#error "Unknown SRCU implementation specified to kernel configuration"
#else #else
/* Dummy definition for things like notifiers. Actual use gets link error. */ #error "Unknown SRCU implementation specified to kernel configuration"
struct srcu_struct { };
#endif #endif
void call_srcu(struct srcu_struct *ssp, struct rcu_head *head, 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) ...@@ -78,11 +75,7 @@ static inline void __srcu_read_unlock_nmisafe(struct srcu_struct *ssp, int idx)
} }
#endif /* CONFIG_NEED_SRCU_NMI_SAFE */ #endif /* CONFIG_NEED_SRCU_NMI_SAFE */
#ifdef CONFIG_SRCU
void srcu_init(void); void srcu_init(void);
#else /* #ifdef CONFIG_SRCU */
static inline void srcu_init(void) { }
#endif /* #else #ifdef CONFIG_SRCU */
#ifdef CONFIG_DEBUG_LOCK_ALLOC #ifdef CONFIG_DEBUG_LOCK_ALLOC
......
...@@ -54,21 +54,17 @@ config RCU_EXPERT ...@@ -54,21 +54,17 @@ config RCU_EXPERT
Say N if you are unsure. Say N if you are unsure.
config SRCU config SRCU
bool def_bool y
help
This option selects the sleepable version of RCU. This version
permits arbitrary sleeping or blocking within RCU read-side critical
sections.
config TINY_SRCU config TINY_SRCU
bool bool
default y if SRCU && TINY_RCU default y if TINY_RCU
help help
This option selects the single-CPU non-preemptible version of SRCU. This option selects the single-CPU non-preemptible version of SRCU.
config TREE_SRCU config TREE_SRCU
bool bool
default y if SRCU && !TINY_RCU default y if !TINY_RCU
help help
This option selects the full-fledged version of SRCU. This option selects the full-fledged version of SRCU.
...@@ -77,7 +73,6 @@ config NEED_SRCU_NMI_SAFE ...@@ -77,7 +73,6 @@ config NEED_SRCU_NMI_SAFE
config TASKS_RCU_GENERIC config TASKS_RCU_GENERIC
def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
select SRCU
help help
This option enables generic infrastructure code supporting This option enables generic infrastructure code supporting
task-based RCU implementations. Not for manual selection. task-based RCU implementations. Not for manual selection.
......
...@@ -27,7 +27,6 @@ config RCU_SCALE_TEST ...@@ -27,7 +27,6 @@ config RCU_SCALE_TEST
tristate "performance tests for RCU" tristate "performance tests for RCU"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
select TORTURE_TEST select TORTURE_TEST
select SRCU
default n default n
help help
This option provides a kernel module that runs performance This option provides a kernel module that runs performance
...@@ -43,7 +42,6 @@ config RCU_TORTURE_TEST ...@@ -43,7 +42,6 @@ config RCU_TORTURE_TEST
tristate "torture tests for RCU" tristate "torture tests for RCU"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
select TORTURE_TEST select TORTURE_TEST
select SRCU
default n default n
help help
This option provides a kernel module that runs torture tests This option provides a kernel module that runs torture tests
...@@ -59,7 +57,6 @@ config RCU_REF_SCALE_TEST ...@@ -59,7 +57,6 @@ config RCU_REF_SCALE_TEST
tristate "Scalability tests for read-side synchronization (RCU and others)" tristate "Scalability tests for read-side synchronization (RCU and others)"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
select TORTURE_TEST select TORTURE_TEST
select SRCU
default n default n
help help
This option provides a kernel module that runs performance tests This option provides a kernel module that runs performance tests
......
...@@ -286,7 +286,7 @@ void rcu_test_sync_prims(void); ...@@ -286,7 +286,7 @@ void rcu_test_sync_prims(void);
*/ */
extern void resched_cpu(int cpu); 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> #include <linux/rcu_node_tree.h>
...@@ -375,6 +375,10 @@ extern void rcu_init_geometry(void); ...@@ -375,6 +375,10 @@ extern void rcu_init_geometry(void);
(cpu) <= rnp->grphi; \ (cpu) <= rnp->grphi; \
(cpu) = rcu_find_next_bit((rnp), (cpu) + 1 - (rnp->grplo), (mask))) (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. * Wrappers for the rcu_node::lock acquire and release.
* *
...@@ -437,7 +441,7 @@ do { \ ...@@ -437,7 +441,7 @@ do { \
#define raw_lockdep_assert_held_rcu_node(p) \ #define raw_lockdep_assert_held_rcu_node(p) \
lockdep_assert_held(&ACCESS_PRIVATE(p, lock)) 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 #ifdef CONFIG_TINY_RCU
/* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */ /* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */
......
...@@ -224,7 +224,7 @@ void rcu_test_sync_prims(void) ...@@ -224,7 +224,7 @@ void rcu_test_sync_prims(void)
synchronize_rcu_expedited(); 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. * Switch to run-time mode once RCU has fully initialized.
...@@ -239,7 +239,7 @@ static int __init rcu_set_runtime_mode(void) ...@@ -239,7 +239,7 @@ static int __init rcu_set_runtime_mode(void)
} }
core_initcall(rcu_set_runtime_mode); 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 #ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key rcu_lock_key; static struct lock_class_key rcu_lock_key;
...@@ -559,10 +559,8 @@ static void early_boot_test_call_rcu(void) ...@@ -559,10 +559,8 @@ static void early_boot_test_call_rcu(void)
struct early_boot_kfree_rcu *rhp; struct early_boot_kfree_rcu *rhp;
call_rcu(&head, test_callback); call_rcu(&head, test_callback);
if (IS_ENABLED(CONFIG_SRCU)) { early_srcu_cookie = start_poll_synchronize_srcu(&early_srcu);
early_srcu_cookie = start_poll_synchronize_srcu(&early_srcu); call_srcu(&early_srcu, &shead, test_callback);
call_srcu(&early_srcu, &shead, test_callback);
}
rhp = kmalloc(sizeof(*rhp), GFP_KERNEL); rhp = kmalloc(sizeof(*rhp), GFP_KERNEL);
if (!WARN_ON_ONCE(!rhp)) if (!WARN_ON_ONCE(!rhp))
kfree_rcu(rhp, rh); kfree_rcu(rhp, rh);
...@@ -585,11 +583,9 @@ static int rcu_verify_early_boot_tests(void) ...@@ -585,11 +583,9 @@ static int rcu_verify_early_boot_tests(void)
if (rcu_self_test) { if (rcu_self_test) {
early_boot_test_counter++; early_boot_test_counter++;
rcu_barrier(); rcu_barrier();
if (IS_ENABLED(CONFIG_SRCU)) { early_boot_test_counter++;
early_boot_test_counter++; srcu_barrier(&early_srcu);
srcu_barrier(&early_srcu); WARN_ON_ONCE(!poll_state_synchronize_srcu(&early_srcu, early_srcu_cookie));
WARN_ON_ONCE(!poll_state_synchronize_srcu(&early_srcu, early_srcu_cookie));
}
} }
if (rcu_self_test_counter != early_boot_test_counter) { if (rcu_self_test_counter != early_boot_test_counter) {
WARN_ON(1); WARN_ON(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment