0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _LINUX_SRCU_TREE_H
0012 #define _LINUX_SRCU_TREE_H
0013
0014 #include <linux/rcu_node_tree.h>
0015 #include <linux/completion.h>
0016
0017 struct srcu_node;
0018 struct srcu_struct;
0019
0020
0021
0022
0023
0024 struct srcu_data {
0025
0026 unsigned long srcu_lock_count[2];
0027 unsigned long srcu_unlock_count[2];
0028
0029
0030 spinlock_t __private lock ____cacheline_internodealigned_in_smp;
0031 struct rcu_segcblist srcu_cblist;
0032 unsigned long srcu_gp_seq_needed;
0033 unsigned long srcu_gp_seq_needed_exp;
0034 bool srcu_cblist_invoking;
0035 struct timer_list delay_work;
0036 struct work_struct work;
0037 struct rcu_head srcu_barrier_head;
0038 struct srcu_node *mynode;
0039 unsigned long grpmask;
0040
0041 int cpu;
0042 struct srcu_struct *ssp;
0043 };
0044
0045
0046
0047
0048 struct srcu_node {
0049 spinlock_t __private lock;
0050 unsigned long srcu_have_cbs[4];
0051
0052 unsigned long srcu_data_have_cbs[4];
0053 unsigned long srcu_gp_seq_needed_exp;
0054 struct srcu_node *srcu_parent;
0055 int grplo;
0056 int grphi;
0057 };
0058
0059
0060
0061
0062 struct srcu_struct {
0063 struct srcu_node *node;
0064 struct srcu_node *level[RCU_NUM_LVLS + 1];
0065
0066 int srcu_size_state;
0067 struct mutex srcu_cb_mutex;
0068 spinlock_t __private lock;
0069 struct mutex srcu_gp_mutex;
0070 unsigned int srcu_idx;
0071 unsigned long srcu_gp_seq;
0072 unsigned long srcu_gp_seq_needed;
0073 unsigned long srcu_gp_seq_needed_exp;
0074 unsigned long srcu_gp_start;
0075 unsigned long srcu_last_gp_end;
0076 unsigned long srcu_size_jiffies;
0077 unsigned long srcu_n_lock_retries;
0078 unsigned long srcu_n_exp_nodelay;
0079 struct srcu_data __percpu *sda;
0080 bool sda_is_static;
0081 unsigned long srcu_barrier_seq;
0082 struct mutex srcu_barrier_mutex;
0083 struct completion srcu_barrier_completion;
0084
0085 atomic_t srcu_barrier_cpu_cnt;
0086
0087
0088 unsigned long reschedule_jiffies;
0089 unsigned long reschedule_count;
0090 struct delayed_work work;
0091 struct lockdep_map dep_map;
0092 };
0093
0094
0095 #define SRCU_SIZE_SMALL 0
0096 #define SRCU_SIZE_ALLOC 1
0097 #define SRCU_SIZE_WAIT_BARRIER 2
0098 #define SRCU_SIZE_WAIT_CALL 3
0099 #define SRCU_SIZE_WAIT_CBS1 4
0100 #define SRCU_SIZE_WAIT_CBS2 5
0101 #define SRCU_SIZE_WAIT_CBS3 6
0102 #define SRCU_SIZE_WAIT_CBS4 7
0103 #define SRCU_SIZE_BIG 8
0104
0105
0106 #define SRCU_STATE_IDLE 0
0107 #define SRCU_STATE_SCAN1 1
0108 #define SRCU_STATE_SCAN2 2
0109
0110 #define __SRCU_STRUCT_INIT(name, pcpu_name) \
0111 { \
0112 .sda = &pcpu_name, \
0113 .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
0114 .srcu_gp_seq_needed = -1UL, \
0115 .work = __DELAYED_WORK_INITIALIZER(name.work, NULL, 0), \
0116 __SRCU_DEP_MAP_INIT(name) \
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 #ifdef MODULE
0139 # define __DEFINE_SRCU(name, is_static) \
0140 is_static struct srcu_struct name; \
0141 extern struct srcu_struct * const __srcu_struct_##name; \
0142 struct srcu_struct * const __srcu_struct_##name \
0143 __section("___srcu_struct_ptrs") = &name
0144 #else
0145 # define __DEFINE_SRCU(name, is_static) \
0146 static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \
0147 is_static struct srcu_struct name = \
0148 __SRCU_STRUCT_INIT(name, name##_srcu_data)
0149 #endif
0150 #define DEFINE_SRCU(name) __DEFINE_SRCU(name, )
0151 #define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
0152
0153 void synchronize_srcu_expedited(struct srcu_struct *ssp);
0154 void srcu_barrier(struct srcu_struct *ssp);
0155 void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf);
0156
0157 #endif