aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/spinlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/spinlock.c')
-rw-r--r--kernel/spinlock.c96
1 files changed, 75 insertions, 21 deletions
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index d1b810782bc4..d48143eafbfd 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -7,31 +7,27 @@
7 * 7 *
8 * This file contains the spinlock/rwlock implementations for the 8 * This file contains the spinlock/rwlock implementations for the
9 * SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them) 9 * SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them)
10 *
11 * Note that some architectures have special knowledge about the
12 * stack frames of these functions in their profile_pc. If you
13 * change anything significant here that could change the stack
14 * frame contact the architecture maintainers.
10 */ 15 */
11 16
12#include <linux/config.h>
13#include <linux/linkage.h> 17#include <linux/linkage.h>
14#include <linux/preempt.h> 18#include <linux/preempt.h>
15#include <linux/spinlock.h> 19#include <linux/spinlock.h>
16#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/debug_locks.h>
17#include <linux/module.h> 22#include <linux/module.h>
18 23
19/*
20 * Generic declaration of the raw read_trylock() function,
21 * architectures are supposed to optimize this:
22 */
23int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock)
24{
25 __raw_read_lock(lock);
26 return 1;
27}
28EXPORT_SYMBOL(generic__raw_read_trylock);
29
30int __lockfunc _spin_trylock(spinlock_t *lock) 24int __lockfunc _spin_trylock(spinlock_t *lock)
31{ 25{
32 preempt_disable(); 26 preempt_disable();
33 if (_raw_spin_trylock(lock)) 27 if (_raw_spin_trylock(lock)) {
28 spin_acquire(&lock->dep_map, 0, 1, _RET_IP_);
34 return 1; 29 return 1;
30 }
35 31
36 preempt_enable(); 32 preempt_enable();
37 return 0; 33 return 0;
@@ -41,8 +37,10 @@ EXPORT_SYMBOL(_spin_trylock);
41int __lockfunc _read_trylock(rwlock_t *lock) 37int __lockfunc _read_trylock(rwlock_t *lock)
42{ 38{
43 preempt_disable(); 39 preempt_disable();
44 if (_raw_read_trylock(lock)) 40 if (_raw_read_trylock(lock)) {
41 rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_);
45 return 1; 42 return 1;
43 }
46 44
47 preempt_enable(); 45 preempt_enable();
48 return 0; 46 return 0;
@@ -52,19 +50,28 @@ EXPORT_SYMBOL(_read_trylock);
52int __lockfunc _write_trylock(rwlock_t *lock) 50int __lockfunc _write_trylock(rwlock_t *lock)
53{ 51{
54 preempt_disable(); 52 preempt_disable();
55 if (_raw_write_trylock(lock)) 53 if (_raw_write_trylock(lock)) {
54 rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_);
56 return 1; 55 return 1;
56 }
57 57
58 preempt_enable(); 58 preempt_enable();
59 return 0; 59 return 0;
60} 60}
61EXPORT_SYMBOL(_write_trylock); 61EXPORT_SYMBOL(_write_trylock);
62 62
63#if !defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) 63/*
64 * If lockdep is enabled then we use the non-preemption spin-ops
65 * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
66 * not re-enabled during lock-acquire (which the preempt-spin-ops do):
67 */
68#if !defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) || \
69 defined(CONFIG_DEBUG_LOCK_ALLOC)
64 70
65void __lockfunc _read_lock(rwlock_t *lock) 71void __lockfunc _read_lock(rwlock_t *lock)
66{ 72{
67 preempt_disable(); 73 preempt_disable();
74 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
68 _raw_read_lock(lock); 75 _raw_read_lock(lock);
69} 76}
70EXPORT_SYMBOL(_read_lock); 77EXPORT_SYMBOL(_read_lock);
@@ -75,7 +82,17 @@ unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
75 82
76 local_irq_save(flags); 83 local_irq_save(flags);
77 preempt_disable(); 84 preempt_disable();
85 spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
86 /*
87 * On lockdep we dont want the hand-coded irq-enable of
88 * _raw_spin_lock_flags() code, because lockdep assumes
89 * that interrupts are not re-enabled during lock-acquire:
90 */
91#ifdef CONFIG_PROVE_LOCKING
92 _raw_spin_lock(lock);
93#else
78 _raw_spin_lock_flags(lock, &flags); 94 _raw_spin_lock_flags(lock, &flags);
95#endif
79 return flags; 96 return flags;
80} 97}
81EXPORT_SYMBOL(_spin_lock_irqsave); 98EXPORT_SYMBOL(_spin_lock_irqsave);
@@ -84,6 +101,7 @@ void __lockfunc _spin_lock_irq(spinlock_t *lock)
84{ 101{
85 local_irq_disable(); 102 local_irq_disable();
86 preempt_disable(); 103 preempt_disable();
104 spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
87 _raw_spin_lock(lock); 105 _raw_spin_lock(lock);
88} 106}
89EXPORT_SYMBOL(_spin_lock_irq); 107EXPORT_SYMBOL(_spin_lock_irq);
@@ -92,6 +110,7 @@ void __lockfunc _spin_lock_bh(spinlock_t *lock)
92{ 110{
93 local_bh_disable(); 111 local_bh_disable();
94 preempt_disable(); 112 preempt_disable();
113 spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
95 _raw_spin_lock(lock); 114 _raw_spin_lock(lock);
96} 115}
97EXPORT_SYMBOL(_spin_lock_bh); 116EXPORT_SYMBOL(_spin_lock_bh);
@@ -102,6 +121,7 @@ unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
102 121
103 local_irq_save(flags); 122 local_irq_save(flags);
104 preempt_disable(); 123 preempt_disable();
124 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
105 _raw_read_lock(lock); 125 _raw_read_lock(lock);
106 return flags; 126 return flags;
107} 127}
@@ -111,6 +131,7 @@ void __lockfunc _read_lock_irq(rwlock_t *lock)
111{ 131{
112 local_irq_disable(); 132 local_irq_disable();
113 preempt_disable(); 133 preempt_disable();
134 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
114 _raw_read_lock(lock); 135 _raw_read_lock(lock);
115} 136}
116EXPORT_SYMBOL(_read_lock_irq); 137EXPORT_SYMBOL(_read_lock_irq);
@@ -119,6 +140,7 @@ void __lockfunc _read_lock_bh(rwlock_t *lock)
119{ 140{
120 local_bh_disable(); 141 local_bh_disable();
121 preempt_disable(); 142 preempt_disable();
143 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
122 _raw_read_lock(lock); 144 _raw_read_lock(lock);
123} 145}
124EXPORT_SYMBOL(_read_lock_bh); 146EXPORT_SYMBOL(_read_lock_bh);
@@ -129,6 +151,7 @@ unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
129 151
130 local_irq_save(flags); 152 local_irq_save(flags);
131 preempt_disable(); 153 preempt_disable();
154 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
132 _raw_write_lock(lock); 155 _raw_write_lock(lock);
133 return flags; 156 return flags;
134} 157}
@@ -138,6 +161,7 @@ void __lockfunc _write_lock_irq(rwlock_t *lock)
138{ 161{
139 local_irq_disable(); 162 local_irq_disable();
140 preempt_disable(); 163 preempt_disable();
164 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
141 _raw_write_lock(lock); 165 _raw_write_lock(lock);
142} 166}
143EXPORT_SYMBOL(_write_lock_irq); 167EXPORT_SYMBOL(_write_lock_irq);
@@ -146,6 +170,7 @@ void __lockfunc _write_lock_bh(rwlock_t *lock)
146{ 170{
147 local_bh_disable(); 171 local_bh_disable();
148 preempt_disable(); 172 preempt_disable();
173 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
149 _raw_write_lock(lock); 174 _raw_write_lock(lock);
150} 175}
151EXPORT_SYMBOL(_write_lock_bh); 176EXPORT_SYMBOL(_write_lock_bh);
@@ -153,6 +178,7 @@ EXPORT_SYMBOL(_write_lock_bh);
153void __lockfunc _spin_lock(spinlock_t *lock) 178void __lockfunc _spin_lock(spinlock_t *lock)
154{ 179{
155 preempt_disable(); 180 preempt_disable();
181 spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
156 _raw_spin_lock(lock); 182 _raw_spin_lock(lock);
157} 183}
158 184
@@ -161,6 +187,7 @@ EXPORT_SYMBOL(_spin_lock);
161void __lockfunc _write_lock(rwlock_t *lock) 187void __lockfunc _write_lock(rwlock_t *lock)
162{ 188{
163 preempt_disable(); 189 preempt_disable();
190 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
164 _raw_write_lock(lock); 191 _raw_write_lock(lock);
165} 192}
166 193
@@ -256,8 +283,22 @@ BUILD_LOCK_OPS(write, rwlock);
256 283
257#endif /* CONFIG_PREEMPT */ 284#endif /* CONFIG_PREEMPT */
258 285
286#ifdef CONFIG_DEBUG_LOCK_ALLOC
287
288void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
289{
290 preempt_disable();
291 spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
292 _raw_spin_lock(lock);
293}
294
295EXPORT_SYMBOL(_spin_lock_nested);
296
297#endif
298
259void __lockfunc _spin_unlock(spinlock_t *lock) 299void __lockfunc _spin_unlock(spinlock_t *lock)
260{ 300{
301 spin_release(&lock->dep_map, 1, _RET_IP_);
261 _raw_spin_unlock(lock); 302 _raw_spin_unlock(lock);
262 preempt_enable(); 303 preempt_enable();
263} 304}
@@ -265,6 +306,7 @@ EXPORT_SYMBOL(_spin_unlock);
265 306
266void __lockfunc _write_unlock(rwlock_t *lock) 307void __lockfunc _write_unlock(rwlock_t *lock)
267{ 308{
309 rwlock_release(&lock->dep_map, 1, _RET_IP_);
268 _raw_write_unlock(lock); 310 _raw_write_unlock(lock);
269 preempt_enable(); 311 preempt_enable();
270} 312}
@@ -272,6 +314,7 @@ EXPORT_SYMBOL(_write_unlock);
272 314
273void __lockfunc _read_unlock(rwlock_t *lock) 315void __lockfunc _read_unlock(rwlock_t *lock)
274{ 316{
317 rwlock_release(&lock->dep_map, 1, _RET_IP_);
275 _raw_read_unlock(lock); 318 _raw_read_unlock(lock);
276 preempt_enable(); 319 preempt_enable();
277} 320}
@@ -279,6 +322,7 @@ EXPORT_SYMBOL(_read_unlock);
279 322
280void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) 323void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
281{ 324{
325 spin_release(&lock->dep_map, 1, _RET_IP_);
282 _raw_spin_unlock(lock); 326 _raw_spin_unlock(lock);
283 local_irq_restore(flags); 327 local_irq_restore(flags);
284 preempt_enable(); 328 preempt_enable();
@@ -287,6 +331,7 @@ EXPORT_SYMBOL(_spin_unlock_irqrestore);
287 331
288void __lockfunc _spin_unlock_irq(spinlock_t *lock) 332void __lockfunc _spin_unlock_irq(spinlock_t *lock)
289{ 333{
334 spin_release(&lock->dep_map, 1, _RET_IP_);
290 _raw_spin_unlock(lock); 335 _raw_spin_unlock(lock);
291 local_irq_enable(); 336 local_irq_enable();
292 preempt_enable(); 337 preempt_enable();
@@ -295,14 +340,16 @@ EXPORT_SYMBOL(_spin_unlock_irq);
295 340
296void __lockfunc _spin_unlock_bh(spinlock_t *lock) 341void __lockfunc _spin_unlock_bh(spinlock_t *lock)
297{ 342{
343 spin_release(&lock->dep_map, 1, _RET_IP_);
298 _raw_spin_unlock(lock); 344 _raw_spin_unlock(lock);
299 preempt_enable_no_resched(); 345 preempt_enable_no_resched();
300 local_bh_enable(); 346 local_bh_enable_ip((unsigned long)__builtin_return_address(0));
301} 347}
302EXPORT_SYMBOL(_spin_unlock_bh); 348EXPORT_SYMBOL(_spin_unlock_bh);
303 349
304void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 350void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
305{ 351{
352 rwlock_release(&lock->dep_map, 1, _RET_IP_);
306 _raw_read_unlock(lock); 353 _raw_read_unlock(lock);
307 local_irq_restore(flags); 354 local_irq_restore(flags);
308 preempt_enable(); 355 preempt_enable();
@@ -311,6 +358,7 @@ EXPORT_SYMBOL(_read_unlock_irqrestore);
311 358
312void __lockfunc _read_unlock_irq(rwlock_t *lock) 359void __lockfunc _read_unlock_irq(rwlock_t *lock)
313{ 360{
361 rwlock_release(&lock->dep_map, 1, _RET_IP_);
314 _raw_read_unlock(lock); 362 _raw_read_unlock(lock);
315 local_irq_enable(); 363 local_irq_enable();
316 preempt_enable(); 364 preempt_enable();
@@ -319,14 +367,16 @@ EXPORT_SYMBOL(_read_unlock_irq);
319 367
320void __lockfunc _read_unlock_bh(rwlock_t *lock) 368void __lockfunc _read_unlock_bh(rwlock_t *lock)
321{ 369{
370 rwlock_release(&lock->dep_map, 1, _RET_IP_);
322 _raw_read_unlock(lock); 371 _raw_read_unlock(lock);
323 preempt_enable_no_resched(); 372 preempt_enable_no_resched();
324 local_bh_enable(); 373 local_bh_enable_ip((unsigned long)__builtin_return_address(0));
325} 374}
326EXPORT_SYMBOL(_read_unlock_bh); 375EXPORT_SYMBOL(_read_unlock_bh);
327 376
328void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 377void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
329{ 378{
379 rwlock_release(&lock->dep_map, 1, _RET_IP_);
330 _raw_write_unlock(lock); 380 _raw_write_unlock(lock);
331 local_irq_restore(flags); 381 local_irq_restore(flags);
332 preempt_enable(); 382 preempt_enable();
@@ -335,6 +385,7 @@ EXPORT_SYMBOL(_write_unlock_irqrestore);
335 385
336void __lockfunc _write_unlock_irq(rwlock_t *lock) 386void __lockfunc _write_unlock_irq(rwlock_t *lock)
337{ 387{
388 rwlock_release(&lock->dep_map, 1, _RET_IP_);
338 _raw_write_unlock(lock); 389 _raw_write_unlock(lock);
339 local_irq_enable(); 390 local_irq_enable();
340 preempt_enable(); 391 preempt_enable();
@@ -343,9 +394,10 @@ EXPORT_SYMBOL(_write_unlock_irq);
343 394
344void __lockfunc _write_unlock_bh(rwlock_t *lock) 395void __lockfunc _write_unlock_bh(rwlock_t *lock)
345{ 396{
397 rwlock_release(&lock->dep_map, 1, _RET_IP_);
346 _raw_write_unlock(lock); 398 _raw_write_unlock(lock);
347 preempt_enable_no_resched(); 399 preempt_enable_no_resched();
348 local_bh_enable(); 400 local_bh_enable_ip((unsigned long)__builtin_return_address(0));
349} 401}
350EXPORT_SYMBOL(_write_unlock_bh); 402EXPORT_SYMBOL(_write_unlock_bh);
351 403
@@ -353,11 +405,13 @@ int __lockfunc _spin_trylock_bh(spinlock_t *lock)
353{ 405{
354 local_bh_disable(); 406 local_bh_disable();
355 preempt_disable(); 407 preempt_disable();
356 if (_raw_spin_trylock(lock)) 408 if (_raw_spin_trylock(lock)) {
409 spin_acquire(&lock->dep_map, 0, 1, _RET_IP_);
357 return 1; 410 return 1;
411 }
358 412
359 preempt_enable_no_resched(); 413 preempt_enable_no_resched();
360 local_bh_enable(); 414 local_bh_enable_ip((unsigned long)__builtin_return_address(0));
361 return 0; 415 return 0;
362} 416}
363EXPORT_SYMBOL(_spin_trylock_bh); 417EXPORT_SYMBOL(_spin_trylock_bh);