Skip to content

Commit

Permalink
srcu: Make Tiny SRCU able to operate in preemptible kernels
Browse files Browse the repository at this point in the history
Given that SRCU allows its read-side critical sections are not just
preemptible, but also allow general blocking, there is not much
reason to restrict Tiny SRCU to non-preemptible kernels.  This commit
therefore removes Tiny SRCU dependencies on non-preemptibility, primarily
surrounding its interaction with rcutorture and early boot.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Ankur Arora <ankur.a.arora@oracle.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: <bpf@vger.kernel.org>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
  • Loading branch information
Paul E. McKenney authored and Boqun Feng committed Feb 5, 2025
1 parent 2014c95 commit da2ac56
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
9 changes: 6 additions & 3 deletions kernel/rcu/rcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,6 @@ void srcutorture_get_gp_data(struct srcu_struct *sp, int *flags,
static inline bool rcu_watching_zero_in_eqs(int cpu, int *vp) { return false; }
static inline unsigned long rcu_get_gp_seq(void) { return 0; }
static inline unsigned long rcu_exp_batches_completed(void) { return 0; }
static inline unsigned long
srcu_batches_completed(struct srcu_struct *sp) { return 0; }
static inline void rcu_force_quiescent_state(void) { }
static inline bool rcu_check_boost_fail(unsigned long gp_state, int *cpup) { return true; }
static inline void show_rcu_gp_kthreads(void) { }
Expand All @@ -624,7 +622,6 @@ static inline void rcu_gp_slow_unregister(atomic_t *rgssp) { }
bool rcu_watching_zero_in_eqs(int cpu, int *vp);
unsigned long rcu_get_gp_seq(void);
unsigned long rcu_exp_batches_completed(void);
unsigned long srcu_batches_completed(struct srcu_struct *sp);
bool rcu_check_boost_fail(unsigned long gp_state, int *cpup);
void show_rcu_gp_kthreads(void);
int rcu_get_gp_kthreads_prio(void);
Expand All @@ -636,6 +633,12 @@ void rcu_gp_slow_register(atomic_t *rgssp);
void rcu_gp_slow_unregister(atomic_t *rgssp);
#endif /* #else #ifdef CONFIG_TINY_RCU */

#ifdef CONFIG_TINY_SRCU
static inline unsigned long srcu_batches_completed(struct srcu_struct *sp) { return 0; }
#else // #ifdef CONFIG_TINY_SRCU
unsigned long srcu_batches_completed(struct srcu_struct *sp);
#endif // #else // #ifdef CONFIG_TINY_SRCU

#ifdef CONFIG_RCU_NOCB_CPU
void rcu_bind_current_to_nocb(void);
#else
Expand Down
6 changes: 6 additions & 0 deletions kernel/rcu/srcutiny.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
#include "rcu_segcblist.h"
#include "rcu.h"

#ifndef CONFIG_TREE_RCU
int rcu_scheduler_active __read_mostly;
#else // #ifndef CONFIG_TREE_RCU
extern int rcu_scheduler_active;
#endif // #else // #ifndef CONFIG_TREE_RCU
static LIST_HEAD(srcu_boot_list);
static bool srcu_init_done;

Expand Down Expand Up @@ -282,11 +286,13 @@ bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie)
}
EXPORT_SYMBOL_GPL(poll_state_synchronize_srcu);

#ifndef CONFIG_TREE_RCU
/* Lockdep diagnostics. */
void __init rcu_scheduler_starting(void)
{
rcu_scheduler_active = RCU_SCHEDULER_RUNNING;
}
#endif // #ifndef CONFIG_TREE_RCU

/*
* Queue work for srcu_struct structures with early boot callbacks.
Expand Down

0 comments on commit da2ac56

Please sign in to comment.