aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/spinlock.h18
-rw-r--r--include/linux/spinlock_api_smp.h2
-rw-r--r--kernel/spinlock.c21
3 files changed, 41 insertions, 0 deletions
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 54ad37089c49..57f670d78f7c 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -199,6 +199,21 @@ do { \
199 BUILD_CHECK_IRQ_FLAGS(flags); \ 199 BUILD_CHECK_IRQ_FLAGS(flags); \
200 flags = _write_lock_irqsave(lock); \ 200 flags = _write_lock_irqsave(lock); \
201 } while (0) 201 } while (0)
202
203#ifdef CONFIG_DEBUG_LOCK_ALLOC
204#define spin_lock_irqsave_nested(lock, flags, subclass) \
205 do { \
206 BUILD_CHECK_IRQ_FLAGS(flags); \
207 flags = _spin_lock_irqsave_nested(lock, subclass); \
208 } while (0)
209#else
210#define spin_lock_irqsave_nested(lock, flags, subclass) \
211 do { \
212 BUILD_CHECK_IRQ_FLAGS(flags); \
213 flags = _spin_lock_irqsave(lock); \
214 } while (0)
215#endif
216
202#else 217#else
203#define spin_lock_irqsave(lock, flags) \ 218#define spin_lock_irqsave(lock, flags) \
204 do { \ 219 do { \
@@ -215,6 +230,9 @@ do { \
215 BUILD_CHECK_IRQ_FLAGS(flags); \ 230 BUILD_CHECK_IRQ_FLAGS(flags); \
216 _write_lock_irqsave(lock, flags); \ 231 _write_lock_irqsave(lock, flags); \
217 } while (0) 232 } while (0)
233#define spin_lock_irqsave_nested(lock, flags, subclass) \
234 spin_lock_irqsave(lock, flags)
235
218#endif 236#endif
219 237
220#define spin_lock_irq(lock) _spin_lock_irq(lock) 238#define spin_lock_irq(lock) _spin_lock_irq(lock)
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h
index 8828b8155e9c..8a2307ce7296 100644
--- a/include/linux/spinlock_api_smp.h
+++ b/include/linux/spinlock_api_smp.h
@@ -32,6 +32,8 @@ void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock);
32void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); 32void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock);
33unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) 33unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
34 __acquires(lock); 34 __acquires(lock);
35unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
36 __acquires(lock);
35unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) 37unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
36 __acquires(lock); 38 __acquires(lock);
37unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) 39unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index 476c3741511b..2c6c2bf85514 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -293,6 +293,27 @@ void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
293} 293}
294 294
295EXPORT_SYMBOL(_spin_lock_nested); 295EXPORT_SYMBOL(_spin_lock_nested);
296unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
297{
298 unsigned long flags;
299
300 local_irq_save(flags);
301 preempt_disable();
302 spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
303 /*
304 * On lockdep we dont want the hand-coded irq-enable of
305 * _raw_spin_lock_flags() code, because lockdep assumes
306 * that interrupts are not re-enabled during lock-acquire:
307 */
308#ifdef CONFIG_PROVE_SPIN_LOCKING
309 _raw_spin_lock(lock);
310#else
311 _raw_spin_lock_flags(lock, &flags);
312#endif
313 return flags;
314}
315
316EXPORT_SYMBOL(_spin_lock_irqsave_nested);
296 317
297#endif 318#endif
298 319