mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
Merge branches 'rcu/staging-core', 'rcu/staging-docs' and 'rcu/staging-kfree', remote-tracking branches 'paul/srcu-cf.2023.04.04a', 'fbq/rcu/lockdep.2023.03.27a' and 'fbq/rcu/rcutorture.2023.03.20a' into rcu/staging
This commit is contained in:
@@ -58,9 +58,9 @@ struct srcu_node {
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-SRCU-domain structure, similar in function to rcu_state.
|
||||
* Per-SRCU-domain structure, update-side data linked from srcu_struct.
|
||||
*/
|
||||
struct srcu_struct {
|
||||
struct srcu_usage {
|
||||
struct srcu_node *node; /* Combining tree. */
|
||||
struct srcu_node *level[RCU_NUM_LVLS + 1];
|
||||
/* First node at each level. */
|
||||
@@ -68,7 +68,6 @@ struct srcu_struct {
|
||||
struct mutex srcu_cb_mutex; /* Serialize CB preparation. */
|
||||
spinlock_t __private lock; /* Protect counters and size state. */
|
||||
struct mutex srcu_gp_mutex; /* Serialize GP work. */
|
||||
unsigned int srcu_idx; /* Current rdr array element. */
|
||||
unsigned long srcu_gp_seq; /* Grace-period seq #. */
|
||||
unsigned long srcu_gp_seq_needed; /* Latest gp_seq needed. */
|
||||
unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */
|
||||
@@ -77,7 +76,6 @@ struct srcu_struct {
|
||||
unsigned long srcu_size_jiffies; /* Current contention-measurement interval. */
|
||||
unsigned long srcu_n_lock_retries; /* Contention events in current interval. */
|
||||
unsigned long srcu_n_exp_nodelay; /* # expedited no-delays in current GP phase. */
|
||||
struct srcu_data __percpu *sda; /* Per-CPU srcu_data array. */
|
||||
bool sda_is_static; /* May ->sda be passed to free_percpu()? */
|
||||
unsigned long srcu_barrier_seq; /* srcu_barrier seq #. */
|
||||
struct mutex srcu_barrier_mutex; /* Serialize barrier ops. */
|
||||
@@ -89,32 +87,68 @@ struct srcu_struct {
|
||||
unsigned long reschedule_jiffies;
|
||||
unsigned long reschedule_count;
|
||||
struct delayed_work work;
|
||||
struct lockdep_map dep_map;
|
||||
struct srcu_struct *srcu_ssp;
|
||||
};
|
||||
|
||||
/* Values for size state variable (->srcu_size_state). */
|
||||
#define SRCU_SIZE_SMALL 0
|
||||
#define SRCU_SIZE_ALLOC 1
|
||||
#define SRCU_SIZE_WAIT_BARRIER 2
|
||||
#define SRCU_SIZE_WAIT_CALL 3
|
||||
#define SRCU_SIZE_WAIT_CBS1 4
|
||||
#define SRCU_SIZE_WAIT_CBS2 5
|
||||
#define SRCU_SIZE_WAIT_CBS3 6
|
||||
#define SRCU_SIZE_WAIT_CBS4 7
|
||||
#define SRCU_SIZE_BIG 8
|
||||
/*
|
||||
* Per-SRCU-domain structure, similar in function to rcu_state.
|
||||
*/
|
||||
struct srcu_struct {
|
||||
unsigned int srcu_idx; /* Current rdr array element. */
|
||||
struct srcu_data __percpu *sda; /* Per-CPU srcu_data array. */
|
||||
struct lockdep_map dep_map;
|
||||
struct srcu_usage *srcu_sup; /* Update-side data. */
|
||||
};
|
||||
|
||||
// Values for size state variable (->srcu_size_state). Once the state
|
||||
// has been set to SRCU_SIZE_ALLOC, the grace-period code advances through
|
||||
// this state machine one step per grace period until the SRCU_SIZE_BIG state
|
||||
// is reached. Otherwise, the state machine remains in the SRCU_SIZE_SMALL
|
||||
// state indefinitely.
|
||||
#define SRCU_SIZE_SMALL 0 // No srcu_node combining tree, ->node == NULL
|
||||
#define SRCU_SIZE_ALLOC 1 // An srcu_node tree is being allocated, initialized,
|
||||
// and then referenced by ->node. It will not be used.
|
||||
#define SRCU_SIZE_WAIT_BARRIER 2 // The srcu_node tree starts being used by everything
|
||||
// except call_srcu(), especially by srcu_barrier().
|
||||
// By the end of this state, all CPUs and threads
|
||||
// are aware of this tree's existence.
|
||||
#define SRCU_SIZE_WAIT_CALL 3 // The srcu_node tree starts being used by call_srcu().
|
||||
// By the end of this state, all of the call_srcu()
|
||||
// invocations that were running on a non-boot CPU
|
||||
// and using the boot CPU's callback queue will have
|
||||
// completed.
|
||||
#define SRCU_SIZE_WAIT_CBS1 4 // Don't trust the ->srcu_have_cbs[] grace-period
|
||||
#define SRCU_SIZE_WAIT_CBS2 5 // sequence elements or the ->srcu_data_have_cbs[]
|
||||
#define SRCU_SIZE_WAIT_CBS3 6 // CPU-bitmask elements until all four elements of
|
||||
#define SRCU_SIZE_WAIT_CBS4 7 // each array have been initialized.
|
||||
#define SRCU_SIZE_BIG 8 // The srcu_node combining tree is fully initialized
|
||||
// and all aspects of it are being put to use.
|
||||
|
||||
/* Values for state variable (bottom bits of ->srcu_gp_seq). */
|
||||
#define SRCU_STATE_IDLE 0
|
||||
#define SRCU_STATE_SCAN1 1
|
||||
#define SRCU_STATE_SCAN2 2
|
||||
|
||||
#define __SRCU_STRUCT_INIT(name, pcpu_name) \
|
||||
{ \
|
||||
.sda = &pcpu_name, \
|
||||
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \
|
||||
.srcu_gp_seq_needed = -1UL, \
|
||||
.work = __DELAYED_WORK_INITIALIZER(name.work, NULL, 0), \
|
||||
__SRCU_DEP_MAP_INIT(name) \
|
||||
#define __SRCU_USAGE_INIT(name) \
|
||||
{ \
|
||||
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \
|
||||
.srcu_gp_seq_needed = -1UL, \
|
||||
.work = __DELAYED_WORK_INITIALIZER(name.work, NULL, 0), \
|
||||
}
|
||||
|
||||
#define __SRCU_STRUCT_INIT_COMMON(name, usage_name) \
|
||||
.srcu_sup = &usage_name, \
|
||||
__SRCU_DEP_MAP_INIT(name)
|
||||
|
||||
#define __SRCU_STRUCT_INIT_MODULE(name, usage_name) \
|
||||
{ \
|
||||
__SRCU_STRUCT_INIT_COMMON(name, usage_name) \
|
||||
}
|
||||
|
||||
#define __SRCU_STRUCT_INIT(name, usage_name, pcpu_name) \
|
||||
{ \
|
||||
.sda = &pcpu_name, \
|
||||
__SRCU_STRUCT_INIT_COMMON(name, usage_name) \
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -137,16 +171,18 @@ struct srcu_struct {
|
||||
* See include/linux/percpu-defs.h for the rules on per-CPU variables.
|
||||
*/
|
||||
#ifdef MODULE
|
||||
# define __DEFINE_SRCU(name, is_static) \
|
||||
is_static struct srcu_struct name; \
|
||||
extern struct srcu_struct * const __srcu_struct_##name; \
|
||||
struct srcu_struct * const __srcu_struct_##name \
|
||||
# define __DEFINE_SRCU(name, is_static) \
|
||||
static struct srcu_usage name##_srcu_usage = __SRCU_USAGE_INIT(name##_srcu_usage); \
|
||||
is_static struct srcu_struct name = __SRCU_STRUCT_INIT_MODULE(name, name##_srcu_usage); \
|
||||
extern struct srcu_struct * const __srcu_struct_##name; \
|
||||
struct srcu_struct * const __srcu_struct_##name \
|
||||
__section("___srcu_struct_ptrs") = &name
|
||||
#else
|
||||
# define __DEFINE_SRCU(name, is_static) \
|
||||
static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \
|
||||
is_static struct srcu_struct name = \
|
||||
__SRCU_STRUCT_INIT(name, name##_srcu_data)
|
||||
# define __DEFINE_SRCU(name, is_static) \
|
||||
static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \
|
||||
static struct srcu_usage name##_srcu_usage = __SRCU_USAGE_INIT(name##_srcu_usage); \
|
||||
is_static struct srcu_struct name = \
|
||||
__SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data)
|
||||
#endif
|
||||
#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)
|
||||
#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
|
||||
|
||||
Reference in New Issue
Block a user