1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_LOCAL_LOCK_H
3 # error "Do not include directly, include linux/local_lock.h"
6 #include <linux/percpu-defs.h>
7 #include <linux/lockdep.h>
9 #ifndef CONFIG_PREEMPT_RT
12 #ifdef CONFIG_DEBUG_LOCK_ALLOC
13 struct lockdep_map dep_map;
14 struct task_struct *owner;
18 #ifdef CONFIG_DEBUG_LOCK_ALLOC
19 # define LOCAL_LOCK_DEBUG_INIT(lockname) \
22 .wait_type_inner = LD_WAIT_CONFIG, \
23 .lock_type = LD_LOCK_PERCPU, \
27 static inline void local_lock_acquire(local_lock_t *l)
29 lock_map_acquire(&l->dep_map);
30 DEBUG_LOCKS_WARN_ON(l->owner);
34 static inline void local_lock_release(local_lock_t *l)
36 DEBUG_LOCKS_WARN_ON(l->owner != current);
38 lock_map_release(&l->dep_map);
41 static inline void local_lock_debug_init(local_lock_t *l)
45 #else /* CONFIG_DEBUG_LOCK_ALLOC */
46 # define LOCAL_LOCK_DEBUG_INIT(lockname)
47 # define local_lock_acquire(__ll) do { typecheck(local_lock_t *, __ll); } while (0)
48 # define local_lock_release(__ll) do { typecheck(local_lock_t *, __ll); } while (0)
49 # define local_lock_debug_init(__ll) do { typecheck(local_lock_t *, __ll); } while (0)
50 #endif /* !CONFIG_DEBUG_LOCK_ALLOC */
52 #define INIT_LOCAL_LOCK(lockname) { LOCAL_LOCK_DEBUG_INIT(lockname) }
54 #define __local_lock_init(lock) \
56 static struct lock_class_key __key; \
58 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
59 lockdep_init_map_type(&(lock)->dep_map, #lock, &__key, \
60 0, LD_WAIT_CONFIG, LD_WAIT_INV, \
62 local_lock_debug_init(lock); \
65 #define __local_lock(lock) \
68 local_lock_acquire(this_cpu_ptr(lock)); \
71 #define __local_lock_irq(lock) \
73 local_irq_disable(); \
74 local_lock_acquire(this_cpu_ptr(lock)); \
77 #define __local_lock_irqsave(lock, flags) \
79 local_irq_save(flags); \
80 local_lock_acquire(this_cpu_ptr(lock)); \
83 #define __local_unlock(lock) \
85 local_lock_release(this_cpu_ptr(lock)); \
89 #define __local_unlock_irq(lock) \
91 local_lock_release(this_cpu_ptr(lock)); \
95 #define __local_unlock_irqrestore(lock, flags) \
97 local_lock_release(this_cpu_ptr(lock)); \
98 local_irq_restore(flags); \
101 #else /* !CONFIG_PREEMPT_RT */
104 * On PREEMPT_RT local_lock maps to a per CPU spinlock, which protects the
105 * critical section while staying preemptible.
107 typedef spinlock_t local_lock_t;
109 #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
111 #define __local_lock_init(l) \
113 local_spin_lock_init((l)); \
116 #define __local_lock(__lock) \
119 spin_lock(this_cpu_ptr((__lock))); \
122 #define __local_lock_irq(lock) __local_lock(lock)
124 #define __local_lock_irqsave(lock, flags) \
126 typecheck(unsigned long, flags); \
128 __local_lock(lock); \
131 #define __local_unlock(__lock) \
133 spin_unlock(this_cpu_ptr((__lock))); \
137 #define __local_unlock_irq(lock) __local_unlock(lock)
139 #define __local_unlock_irqrestore(lock, flags) __local_unlock(lock)
141 #endif /* CONFIG_PREEMPT_RT */