1
2
3
4
5
6
7
8
9
10
11#ifndef _LINUX_SRCU_TREE_H
12#define _LINUX_SRCU_TREE_H
13
14#include <linux/rcu_node_tree.h>
15#include <linux/completion.h>
16
17struct srcu_node;
18struct srcu_struct;
19
20
21
22
23
24struct srcu_data {
25
26 unsigned long srcu_lock_count[2];
27 unsigned long srcu_unlock_count[2];
28
29
30 spinlock_t __private lock ____cacheline_internodealigned_in_smp;
31 struct rcu_segcblist srcu_cblist;
32 unsigned long srcu_gp_seq_needed;
33 unsigned long srcu_gp_seq_needed_exp;
34 bool srcu_cblist_invoking;
35 struct timer_list delay_work;
36 struct work_struct work;
37 struct rcu_head srcu_barrier_head;
38 struct srcu_node *mynode;
39 unsigned long grpmask;
40
41 int cpu;
42 struct srcu_struct *ssp;
43};
44
45
46
47
48struct srcu_node {
49 spinlock_t __private lock;
50 unsigned long srcu_have_cbs[4];
51
52 unsigned long srcu_data_have_cbs[4];
53 unsigned long srcu_gp_seq_needed_exp;
54 struct srcu_node *srcu_parent;
55 int grplo;
56 int grphi;
57};
58
59
60
61
62struct srcu_struct {
63 struct srcu_node *node;
64 struct srcu_node *level[RCU_NUM_LVLS + 1];
65
66 int srcu_size_state;
67 struct mutex srcu_cb_mutex;
68 spinlock_t __private lock;
69 struct mutex srcu_gp_mutex;
70 unsigned int srcu_idx;
71 unsigned long srcu_gp_seq;
72 unsigned long srcu_gp_seq_needed;
73 unsigned long srcu_gp_seq_needed_exp;
74 unsigned long srcu_gp_start;
75 unsigned long srcu_last_gp_end;
76 unsigned long srcu_size_jiffies;
77 unsigned long srcu_n_lock_retries;
78 unsigned long srcu_n_exp_nodelay;
79 struct srcu_data __percpu *sda;
80 bool sda_is_static;
81 unsigned long srcu_barrier_seq;
82 struct mutex srcu_barrier_mutex;
83 struct completion srcu_barrier_completion;
84
85 atomic_t srcu_barrier_cpu_cnt;
86
87
88 unsigned long reschedule_jiffies;
89 unsigned long reschedule_count;
90 struct delayed_work work;
91 struct lockdep_map dep_map;
92};
93
94
95#define SRCU_SIZE_SMALL 0
96#define SRCU_SIZE_ALLOC 1
97#define SRCU_SIZE_WAIT_BARRIER 2
98#define SRCU_SIZE_WAIT_CALL 3
99#define SRCU_SIZE_WAIT_CBS1 4
100#define SRCU_SIZE_WAIT_CBS2 5
101#define SRCU_SIZE_WAIT_CBS3 6
102#define SRCU_SIZE_WAIT_CBS4 7
103#define SRCU_SIZE_BIG 8
104
105
106#define SRCU_STATE_IDLE 0
107#define SRCU_STATE_SCAN1 1
108#define SRCU_STATE_SCAN2 2
109
110#define __SRCU_STRUCT_INIT(name, pcpu_name) \
111{ \
112 .sda = &pcpu_name, \
113 .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
114 .srcu_gp_seq_needed = -1UL, \
115 .work = __DELAYED_WORK_INITIALIZER(name.work, NULL, 0), \
116 __SRCU_DEP_MAP_INIT(name) \
117}
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138#ifdef MODULE
139# define __DEFINE_SRCU(name, is_static) \
140 is_static struct srcu_struct name; \
141 extern struct srcu_struct * const __srcu_struct_##name; \
142 struct srcu_struct * const __srcu_struct_##name \
143 __section("___srcu_struct_ptrs") = &name
144#else
145# define __DEFINE_SRCU(name, is_static) \
146 static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \
147 is_static struct srcu_struct name = \
148 __SRCU_STRUCT_INIT(name, name##_srcu_data)
149#endif
150#define DEFINE_SRCU(name) __DEFINE_SRCU(name, )
151#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
152
153void synchronize_srcu_expedited(struct srcu_struct *ssp);
154void srcu_barrier(struct srcu_struct *ssp);
155void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf);
156
157#endif
158