blob: 5ddab730cb2fb61d664a83d73792792ef9048432 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (2004) Linus Torvalds
3 *
4 * Author: Zwane Mwaikambo <zwane@fsmlabs.com>
5 *
Ingo Molnarfb1c8f92005-09-10 00:25:56 -07006 * Copyright (2004, 2005) Ingo Molnar
7 *
8 * This file contains the spinlock/rwlock implementations for the
9 * SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them)
Andi Kleen0cb91a22006-09-26 10:52:28 +020010 *
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.
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 */
16
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <linux/linkage.h>
18#include <linux/preempt.h>
19#include <linux/spinlock.h>
20#include <linux/interrupt.h>
Ingo Molnar8a25d5d2006-07-03 00:24:54 -070021#include <linux/debug_locks.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/module.h>
23
Heiko Carstens892a7c62009-08-31 14:43:37 +020024#ifndef _spin_trylock
Linus Torvalds1da177e2005-04-16 15:20:36 -070025int __lockfunc _spin_trylock(spinlock_t *lock)
26{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020027 return __spin_trylock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070028}
29EXPORT_SYMBOL(_spin_trylock);
Heiko Carstens892a7c62009-08-31 14:43:37 +020030#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Heiko Carstens892a7c62009-08-31 14:43:37 +020032#ifndef _read_trylock
Linus Torvalds1da177e2005-04-16 15:20:36 -070033int __lockfunc _read_trylock(rwlock_t *lock)
34{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020035 return __read_trylock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070036}
37EXPORT_SYMBOL(_read_trylock);
Heiko Carstens892a7c62009-08-31 14:43:37 +020038#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
Heiko Carstens892a7c62009-08-31 14:43:37 +020040#ifndef _write_trylock
Linus Torvalds1da177e2005-04-16 15:20:36 -070041int __lockfunc _write_trylock(rwlock_t *lock)
42{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020043 return __write_trylock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070044}
45EXPORT_SYMBOL(_write_trylock);
Heiko Carstens892a7c62009-08-31 14:43:37 +020046#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Ingo Molnar8a25d5d2006-07-03 00:24:54 -070048/*
49 * If lockdep is enabled then we use the non-preemption spin-ops
50 * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
51 * not re-enabled during lock-acquire (which the preempt-spin-ops do):
52 */
Nick Piggin95c354f2008-01-30 13:31:20 +010053#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Heiko Carstens892a7c62009-08-31 14:43:37 +020055#ifndef _read_lock
Linus Torvalds1da177e2005-04-16 15:20:36 -070056void __lockfunc _read_lock(rwlock_t *lock)
57{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020058 __read_lock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059}
60EXPORT_SYMBOL(_read_lock);
Heiko Carstens892a7c62009-08-31 14:43:37 +020061#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Heiko Carstens892a7c62009-08-31 14:43:37 +020063#ifndef _spin_lock_irqsave
Linus Torvalds1da177e2005-04-16 15:20:36 -070064unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
65{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020066 return __spin_lock_irqsave(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067}
68EXPORT_SYMBOL(_spin_lock_irqsave);
Heiko Carstens892a7c62009-08-31 14:43:37 +020069#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Heiko Carstens892a7c62009-08-31 14:43:37 +020071#ifndef _spin_lock_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -070072void __lockfunc _spin_lock_irq(spinlock_t *lock)
73{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020074 __spin_lock_irq(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075}
76EXPORT_SYMBOL(_spin_lock_irq);
Heiko Carstens892a7c62009-08-31 14:43:37 +020077#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
Heiko Carstens892a7c62009-08-31 14:43:37 +020079#ifndef _spin_lock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -070080void __lockfunc _spin_lock_bh(spinlock_t *lock)
81{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020082 __spin_lock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070083}
84EXPORT_SYMBOL(_spin_lock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +020085#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
Heiko Carstens892a7c62009-08-31 14:43:37 +020087#ifndef _read_lock_irqsave
Linus Torvalds1da177e2005-04-16 15:20:36 -070088unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
89{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020090 return __read_lock_irqsave(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091}
92EXPORT_SYMBOL(_read_lock_irqsave);
Heiko Carstens892a7c62009-08-31 14:43:37 +020093#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Heiko Carstens892a7c62009-08-31 14:43:37 +020095#ifndef _read_lock_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -070096void __lockfunc _read_lock_irq(rwlock_t *lock)
97{
Heiko Carstens69d0ee72009-08-31 14:43:36 +020098 __read_lock_irq(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099}
100EXPORT_SYMBOL(_read_lock_irq);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200101#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Heiko Carstens892a7c62009-08-31 14:43:37 +0200103#ifndef _read_lock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104void __lockfunc _read_lock_bh(rwlock_t *lock)
105{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200106 __read_lock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108EXPORT_SYMBOL(_read_lock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200109#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
Heiko Carstens892a7c62009-08-31 14:43:37 +0200111#ifndef _write_lock_irqsave
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
113{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200114 return __write_lock_irqsave(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115}
116EXPORT_SYMBOL(_write_lock_irqsave);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200117#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Heiko Carstens892a7c62009-08-31 14:43:37 +0200119#ifndef _write_lock_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120void __lockfunc _write_lock_irq(rwlock_t *lock)
121{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200122 __write_lock_irq(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123}
124EXPORT_SYMBOL(_write_lock_irq);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200125#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Heiko Carstens892a7c62009-08-31 14:43:37 +0200127#ifndef _write_lock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128void __lockfunc _write_lock_bh(rwlock_t *lock)
129{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200130 __write_lock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131}
132EXPORT_SYMBOL(_write_lock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200133#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
Heiko Carstens892a7c62009-08-31 14:43:37 +0200135#ifndef _spin_lock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136void __lockfunc _spin_lock(spinlock_t *lock)
137{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200138 __spin_lock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140EXPORT_SYMBOL(_spin_lock);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200141#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
Heiko Carstens892a7c62009-08-31 14:43:37 +0200143#ifndef _write_lock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144void __lockfunc _write_lock(rwlock_t *lock)
145{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200146 __write_lock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148EXPORT_SYMBOL(_write_lock);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200149#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151#else /* CONFIG_PREEMPT: */
152
153/*
154 * This could be a long-held lock. We both prepare to spin for a long
155 * time (making _this_ CPU preemptable if possible), and we also signal
156 * towards that other CPU that it should break the lock ASAP.
157 *
158 * (We do this in a function because inlining it would be excessive.)
159 */
160
161#define BUILD_LOCK_OPS(op, locktype) \
162void __lockfunc _##op##_lock(locktype##_t *lock) \
163{ \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 for (;;) { \
Oleg Nesterovee25e962006-03-23 03:00:58 -0800165 preempt_disable(); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 if (likely(_raw_##op##_trylock(lock))) \
167 break; \
168 preempt_enable(); \
Oleg Nesterovee25e962006-03-23 03:00:58 -0800169 \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 if (!(lock)->break_lock) \
171 (lock)->break_lock = 1; \
172 while (!op##_can_lock(lock) && (lock)->break_lock) \
Martin Schwidefskyef6edc92006-09-30 23:27:43 -0700173 _raw_##op##_relax(&lock->raw_lock); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 } \
175 (lock)->break_lock = 0; \
176} \
177 \
178EXPORT_SYMBOL(_##op##_lock); \
179 \
180unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
181{ \
182 unsigned long flags; \
183 \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 for (;;) { \
Oleg Nesterovee25e962006-03-23 03:00:58 -0800185 preempt_disable(); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 local_irq_save(flags); \
187 if (likely(_raw_##op##_trylock(lock))) \
188 break; \
189 local_irq_restore(flags); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 preempt_enable(); \
Oleg Nesterovee25e962006-03-23 03:00:58 -0800191 \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 if (!(lock)->break_lock) \
193 (lock)->break_lock = 1; \
194 while (!op##_can_lock(lock) && (lock)->break_lock) \
Martin Schwidefskyef6edc92006-09-30 23:27:43 -0700195 _raw_##op##_relax(&lock->raw_lock); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 } \
197 (lock)->break_lock = 0; \
198 return flags; \
199} \
200 \
201EXPORT_SYMBOL(_##op##_lock_irqsave); \
202 \
203void __lockfunc _##op##_lock_irq(locktype##_t *lock) \
204{ \
205 _##op##_lock_irqsave(lock); \
206} \
207 \
208EXPORT_SYMBOL(_##op##_lock_irq); \
209 \
210void __lockfunc _##op##_lock_bh(locktype##_t *lock) \
211{ \
212 unsigned long flags; \
213 \
214 /* */ \
215 /* Careful: we must exclude softirqs too, hence the */ \
216 /* irq-disabling. We use the generic preemption-aware */ \
217 /* function: */ \
218 /**/ \
219 flags = _##op##_lock_irqsave(lock); \
220 local_bh_disable(); \
221 local_irq_restore(flags); \
222} \
223 \
224EXPORT_SYMBOL(_##op##_lock_bh)
225
226/*
227 * Build preemption-friendly versions of the following
228 * lock-spinning functions:
229 *
230 * _[spin|read|write]_lock()
231 * _[spin|read|write]_lock_irq()
232 * _[spin|read|write]_lock_irqsave()
233 * _[spin|read|write]_lock_bh()
234 */
235BUILD_LOCK_OPS(spin, spinlock);
236BUILD_LOCK_OPS(read, rwlock);
237BUILD_LOCK_OPS(write, rwlock);
238
239#endif /* CONFIG_PREEMPT */
240
Ingo Molnar8a25d5d2006-07-03 00:24:54 -0700241#ifdef CONFIG_DEBUG_LOCK_ALLOC
242
243void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
244{
245 preempt_disable();
246 spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
Peter Zijlstra4fe87742007-07-19 01:48:58 -0700247 LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock);
Ingo Molnar8a25d5d2006-07-03 00:24:54 -0700248}
Ingo Molnar8a25d5d2006-07-03 00:24:54 -0700249EXPORT_SYMBOL(_spin_lock_nested);
Peter Zijlstrab7d39af2008-08-11 09:30:24 +0200250
Arjan van de Vencfd3ef22006-11-25 11:09:37 -0800251unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
252{
253 unsigned long flags;
254
255 local_irq_save(flags);
256 preempt_disable();
257 spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
Robin Holte8c158b2009-04-02 16:59:45 -0700258 LOCK_CONTENDED_FLAGS(lock, _raw_spin_trylock, _raw_spin_lock,
259 _raw_spin_lock_flags, &flags);
Arjan van de Vencfd3ef22006-11-25 11:09:37 -0800260 return flags;
261}
Arjan van de Vencfd3ef22006-11-25 11:09:37 -0800262EXPORT_SYMBOL(_spin_lock_irqsave_nested);
Ingo Molnar8a25d5d2006-07-03 00:24:54 -0700263
Peter Zijlstrab7d39af2008-08-11 09:30:24 +0200264void __lockfunc _spin_lock_nest_lock(spinlock_t *lock,
265 struct lockdep_map *nest_lock)
266{
267 preempt_disable();
268 spin_acquire_nest(&lock->dep_map, 0, 0, nest_lock, _RET_IP_);
269 LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock);
270}
Peter Zijlstrab7d39af2008-08-11 09:30:24 +0200271EXPORT_SYMBOL(_spin_lock_nest_lock);
272
Ingo Molnar8a25d5d2006-07-03 00:24:54 -0700273#endif
274
Heiko Carstens892a7c62009-08-31 14:43:37 +0200275#ifndef _spin_unlock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276void __lockfunc _spin_unlock(spinlock_t *lock)
277{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200278 __spin_unlock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279}
280EXPORT_SYMBOL(_spin_unlock);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200281#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
Heiko Carstens892a7c62009-08-31 14:43:37 +0200283#ifndef _write_unlock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284void __lockfunc _write_unlock(rwlock_t *lock)
285{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200286 __write_unlock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287}
288EXPORT_SYMBOL(_write_unlock);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200289#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
Heiko Carstens892a7c62009-08-31 14:43:37 +0200291#ifndef _read_unlock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292void __lockfunc _read_unlock(rwlock_t *lock)
293{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200294 __read_unlock(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295}
296EXPORT_SYMBOL(_read_unlock);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200297#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298
Heiko Carstens892a7c62009-08-31 14:43:37 +0200299#ifndef _spin_unlock_irqrestore
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
301{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200302 __spin_unlock_irqrestore(lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303}
304EXPORT_SYMBOL(_spin_unlock_irqrestore);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200305#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306
Heiko Carstens892a7c62009-08-31 14:43:37 +0200307#ifndef _spin_unlock_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308void __lockfunc _spin_unlock_irq(spinlock_t *lock)
309{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200310 __spin_unlock_irq(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311}
312EXPORT_SYMBOL(_spin_unlock_irq);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200313#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
Heiko Carstens892a7c62009-08-31 14:43:37 +0200315#ifndef _spin_unlock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316void __lockfunc _spin_unlock_bh(spinlock_t *lock)
317{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200318 __spin_unlock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319}
320EXPORT_SYMBOL(_spin_unlock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200321#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
Heiko Carstens892a7c62009-08-31 14:43:37 +0200323#ifndef _read_unlock_irqrestore
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
325{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200326 __read_unlock_irqrestore(lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327}
328EXPORT_SYMBOL(_read_unlock_irqrestore);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200329#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
Heiko Carstens892a7c62009-08-31 14:43:37 +0200331#ifndef _read_unlock_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332void __lockfunc _read_unlock_irq(rwlock_t *lock)
333{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200334 __read_unlock_irq(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335}
336EXPORT_SYMBOL(_read_unlock_irq);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200337#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
Heiko Carstens892a7c62009-08-31 14:43:37 +0200339#ifndef _read_unlock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340void __lockfunc _read_unlock_bh(rwlock_t *lock)
341{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200342 __read_unlock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343}
344EXPORT_SYMBOL(_read_unlock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200345#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346
Heiko Carstens892a7c62009-08-31 14:43:37 +0200347#ifndef _write_unlock_irqrestore
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
349{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200350 __write_unlock_irqrestore(lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351}
352EXPORT_SYMBOL(_write_unlock_irqrestore);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200353#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
Heiko Carstens892a7c62009-08-31 14:43:37 +0200355#ifndef _write_unlock_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356void __lockfunc _write_unlock_irq(rwlock_t *lock)
357{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200358 __write_unlock_irq(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359}
360EXPORT_SYMBOL(_write_unlock_irq);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200361#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362
Heiko Carstens892a7c62009-08-31 14:43:37 +0200363#ifndef _write_unlock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364void __lockfunc _write_unlock_bh(rwlock_t *lock)
365{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200366 __write_unlock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367}
368EXPORT_SYMBOL(_write_unlock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200369#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Heiko Carstens892a7c62009-08-31 14:43:37 +0200371#ifndef _spin_trylock_bh
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372int __lockfunc _spin_trylock_bh(spinlock_t *lock)
373{
Heiko Carstens69d0ee72009-08-31 14:43:36 +0200374 return __spin_trylock_bh(lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375}
376EXPORT_SYMBOL(_spin_trylock_bh);
Heiko Carstens892a7c62009-08-31 14:43:37 +0200377#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
Steven Rostedt0764d232008-05-12 21:20:44 +0200379notrace int in_lock_functions(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380{
381 /* Linker adds these: start and end of __lockfunc functions */
382 extern char __lock_text_start[], __lock_text_end[];
383
384 return addr >= (unsigned long)__lock_text_start
385 && addr < (unsigned long)__lock_text_end;
386}
387EXPORT_SYMBOL(in_lock_functions);