Branch data Line data Source code
1 : : #ifndef __LINUX_RWLOCK_API_SMP_H
2 : : #define __LINUX_RWLOCK_API_SMP_H
3 : :
4 : : #ifndef __LINUX_SPINLOCK_API_SMP_H
5 : : # error "please don't include this file directly"
6 : : #endif
7 : :
8 : : /*
9 : : * include/linux/rwlock_api_smp.h
10 : : *
11 : : * spinlock API declarations on SMP (and debug)
12 : : * (implemented in kernel/spinlock.c)
13 : : *
14 : : * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
15 : : * Released under the General Public License (GPL).
16 : : */
17 : :
18 : : void __lockfunc _raw_read_lock(rwlock_t *lock) __acquires(lock);
19 : : void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock);
20 : : void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock);
21 : : void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock);
22 : : void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock);
23 : : void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock);
24 : : unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock)
25 : : __acquires(lock);
26 : : unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock)
27 : : __acquires(lock);
28 : : int __lockfunc _raw_read_trylock(rwlock_t *lock);
29 : : int __lockfunc _raw_write_trylock(rwlock_t *lock);
30 : : void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock);
31 : : void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock);
32 : : void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock);
33 : : void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock);
34 : : void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock);
35 : : void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock);
36 : : void __lockfunc
37 : : _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
38 : : __releases(lock);
39 : : void __lockfunc
40 : : _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
41 : : __releases(lock);
42 : :
43 : : #ifdef CONFIG_INLINE_READ_LOCK
44 : : #define _raw_read_lock(lock) __raw_read_lock(lock)
45 : : #endif
46 : :
47 : : #ifdef CONFIG_INLINE_WRITE_LOCK
48 : : #define _raw_write_lock(lock) __raw_write_lock(lock)
49 : : #endif
50 : :
51 : : #ifdef CONFIG_INLINE_READ_LOCK_BH
52 : : #define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock)
53 : : #endif
54 : :
55 : : #ifdef CONFIG_INLINE_WRITE_LOCK_BH
56 : : #define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock)
57 : : #endif
58 : :
59 : : #ifdef CONFIG_INLINE_READ_LOCK_IRQ
60 : : #define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock)
61 : : #endif
62 : :
63 : : #ifdef CONFIG_INLINE_WRITE_LOCK_IRQ
64 : : #define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock)
65 : : #endif
66 : :
67 : : #ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE
68 : : #define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock)
69 : : #endif
70 : :
71 : : #ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
72 : : #define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock)
73 : : #endif
74 : :
75 : : #ifdef CONFIG_INLINE_READ_TRYLOCK
76 : : #define _raw_read_trylock(lock) __raw_read_trylock(lock)
77 : : #endif
78 : :
79 : : #ifdef CONFIG_INLINE_WRITE_TRYLOCK
80 : : #define _raw_write_trylock(lock) __raw_write_trylock(lock)
81 : : #endif
82 : :
83 : : #ifdef CONFIG_INLINE_READ_UNLOCK
84 : : #define _raw_read_unlock(lock) __raw_read_unlock(lock)
85 : : #endif
86 : :
87 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK
88 : : #define _raw_write_unlock(lock) __raw_write_unlock(lock)
89 : : #endif
90 : :
91 : : #ifdef CONFIG_INLINE_READ_UNLOCK_BH
92 : : #define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock)
93 : : #endif
94 : :
95 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK_BH
96 : : #define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock)
97 : : #endif
98 : :
99 : : #ifdef CONFIG_INLINE_READ_UNLOCK_IRQ
100 : : #define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock)
101 : : #endif
102 : :
103 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ
104 : : #define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock)
105 : : #endif
106 : :
107 : : #ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
108 : : #define _raw_read_unlock_irqrestore(lock, flags) \
109 : : __raw_read_unlock_irqrestore(lock, flags)
110 : : #endif
111 : :
112 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
113 : : #define _raw_write_unlock_irqrestore(lock, flags) \
114 : : __raw_write_unlock_irqrestore(lock, flags)
115 : : #endif
116 : :
117 : : static inline int __raw_read_trylock(rwlock_t *lock)
118 : : {
119 : 0 : preempt_disable();
120 [ # # ]: 0 : if (do_raw_read_trylock(lock)) {
121 : : rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_);
122 : : return 1;
123 : : }
124 : 0 : preempt_enable();
125 : : return 0;
126 : : }
127 : :
128 : : static inline int __raw_write_trylock(rwlock_t *lock)
129 : : {
130 : 0 : preempt_disable();
131 [ # # ]: 0 : if (do_raw_write_trylock(lock)) {
132 : : rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_);
133 : : return 1;
134 : : }
135 : 0 : preempt_enable();
136 : : return 0;
137 : : }
138 : :
139 : : /*
140 : : * If lockdep is enabled then we use the non-preemption spin-ops
141 : : * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
142 : : * not re-enabled during lock-acquire (which the preempt-spin-ops do):
143 : : */
144 : : #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
145 : :
146 : : static inline void __raw_read_lock(rwlock_t *lock)
147 : : {
148 : 482130696 : preempt_disable();
149 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
150 : 482162222 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
151 : : }
152 : :
153 : : static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock)
154 : : {
155 : : unsigned long flags;
156 : :
157 : 1903927 : local_irq_save(flags);
158 : 1904587 : preempt_disable();
159 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
160 : 1904597 : LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock,
161 : : do_raw_read_lock_flags, &flags);
162 : : return flags;
163 : : }
164 : :
165 : : static inline void __raw_read_lock_irq(rwlock_t *lock)
166 : : {
167 : 0 : local_irq_disable();
168 : 0 : preempt_disable();
169 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
170 : 0 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
171 : : }
172 : :
173 : : static inline void __raw_read_lock_bh(rwlock_t *lock)
174 : : {
175 : 34696 : __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
176 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
177 : 34699 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
178 : : }
179 : :
180 : : static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock)
181 : : {
182 : : unsigned long flags;
183 : :
184 : 19634 : local_irq_save(flags);
185 : 19636 : preempt_disable();
186 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
187 : 19636 : LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock,
188 : : do_raw_write_lock_flags, &flags);
189 : : return flags;
190 : : }
191 : :
192 : : static inline void __raw_write_lock_irq(rwlock_t *lock)
193 : : {
194 : 8297742 : local_irq_disable();
195 : 8301330 : preempt_disable();
196 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
197 : 8301295 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
198 : : }
199 : :
200 : : static inline void __raw_write_lock_bh(rwlock_t *lock)
201 : : {
202 : 242938 : __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
203 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
204 : 242959 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
205 : : }
206 : :
207 : : static inline void __raw_write_lock(rwlock_t *lock)
208 : : {
209 : 1692126 : preempt_disable();
210 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
211 : 1691895 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
212 : : }
213 : :
214 : : #endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */
215 : :
216 : : static inline void __raw_write_unlock(rwlock_t *lock)
217 : : {
218 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
219 : : do_raw_write_unlock(lock);
220 : 1943513 : preempt_enable();
221 : : }
222 : :
223 : : static inline void __raw_read_unlock(rwlock_t *lock)
224 : : {
225 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
226 : 669580673 : do_raw_read_unlock(lock);
227 : 669653998 : preempt_enable();
228 : : }
229 : :
230 : : static inline void
231 : 1904172 : __raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
232 : : {
233 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
234 : 1904172 : do_raw_read_unlock(lock);
235 [ + - ]: 3806814 : local_irq_restore(flags);
236 : 1904353 : preempt_enable();
237 : 1904303 : }
238 : :
239 : : static inline void __raw_read_unlock_irq(rwlock_t *lock)
240 : : {
241 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
242 : : do_raw_read_unlock(lock);
243 : : local_irq_enable();
244 : : preempt_enable();
245 : : }
246 : :
247 : : static inline void __raw_read_unlock_bh(rwlock_t *lock)
248 : : {
249 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
250 : 34689 : do_raw_read_unlock(lock);
251 : 34696 : __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
252 : : }
253 : :
254 : 19632 : static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
255 : : unsigned long flags)
256 : : {
257 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
258 : : do_raw_write_unlock(lock);
259 [ - + ]: 19636 : local_irq_restore(flags);
260 : 19635 : preempt_enable();
261 : 19632 : }
262 : :
263 : 8239876 : static inline void __raw_write_unlock_irq(rwlock_t *lock)
264 : : {
265 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
266 : : do_raw_write_unlock(lock);
267 : 8244001 : local_irq_enable();
268 : 8244824 : preempt_enable();
269 : 8240889 : }
270 : :
271 : 242605 : static inline void __raw_write_unlock_bh(rwlock_t *lock)
272 : : {
273 : : rwlock_release(&lock->dep_map, 1, _RET_IP_);
274 : : do_raw_write_unlock(lock);
275 : 242591 : __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
276 : 242584 : }
277 : :
278 : : #endif /* __LINUX_RWLOCK_API_SMP_H */
|