1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#ifndef __LINUX_RCUCLASSIC_H
34#define __LINUX_RCUCLASSIC_H
35
36#ifdef __KERNEL__
37
38#include <linux/cache.h>
39#include <linux/spinlock.h>
40#include <linux/threads.h>
41#include <linux/percpu.h>
42#include <linux/cpumask.h>
43#include <linux/seqlock.h>
44
45
46
47struct rcu_ctrlblk {
48 long cur;
49 long completed;
50 int next_pending;
51
52 int signaled;
53
54 spinlock_t lock ____cacheline_internodealigned_in_smp;
55 cpumask_t cpumask;
56
57} ____cacheline_internodealigned_in_smp;
58
59
60static inline int rcu_batch_before(long a, long b)
61{
62 return (a - b) < 0;
63}
64
65
66static inline int rcu_batch_after(long a, long b)
67{
68 return (a - b) > 0;
69}
70
71
72
73
74
75
76struct rcu_data {
77
78 long quiescbatch;
79 int passed_quiesc;
80 int qs_pending;
81
82
83 long batch;
84 struct rcu_head *nxtlist;
85 struct rcu_head **nxttail;
86 long qlen;
87 struct rcu_head *curlist;
88 struct rcu_head **curtail;
89 struct rcu_head *donelist;
90 struct rcu_head **donetail;
91 long blimit;
92 int cpu;
93 struct rcu_head barrier;
94};
95
96DECLARE_PER_CPU(struct rcu_data, rcu_data);
97DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
98
99
100
101
102
103
104
105static inline void rcu_qsctr_inc(int cpu)
106{
107 struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
108 rdp->passed_quiesc = 1;
109}
110static inline void rcu_bh_qsctr_inc(int cpu)
111{
112 struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
113 rdp->passed_quiesc = 1;
114}
115
116extern int rcu_pending(int cpu);
117extern int rcu_needs_cpu(int cpu);
118
119#ifdef CONFIG_DEBUG_LOCK_ALLOC
120extern struct lockdep_map rcu_lock_map;
121# define rcu_read_acquire() \
122 lock_acquire(&rcu_lock_map, 0, 0, 2, 1, _THIS_IP_)
123# define rcu_read_release() lock_release(&rcu_lock_map, 1, _THIS_IP_)
124#else
125# define rcu_read_acquire() do { } while (0)
126# define rcu_read_release() do { } while (0)
127#endif
128
129#define __rcu_read_lock() \
130 do { \
131 preempt_disable(); \
132 __acquire(RCU); \
133 rcu_read_acquire(); \
134 } while (0)
135#define __rcu_read_unlock() \
136 do { \
137 rcu_read_release(); \
138 __release(RCU); \
139 preempt_enable(); \
140 } while (0)
141#define __rcu_read_lock_bh() \
142 do { \
143 local_bh_disable(); \
144 __acquire(RCU_BH); \
145 rcu_read_acquire(); \
146 } while (0)
147#define __rcu_read_unlock_bh() \
148 do { \
149 rcu_read_release(); \
150 __release(RCU_BH); \
151 local_bh_enable(); \
152 } while (0)
153
154#define __synchronize_sched() synchronize_rcu()
155
156extern void __rcu_init(void);
157extern void rcu_check_callbacks(int cpu, int user);
158extern void rcu_restart_cpu(int cpu);
159
160extern long rcu_batches_completed(void);
161extern long rcu_batches_completed_bh(void);
162
163#define rcu_enter_nohz() do { } while (0)
164#define rcu_exit_nohz() do { } while (0)
165
166#endif
167#endif
168