1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_LOCAL_LOCK_H
3 # error "Do not include directly, include linux/local_lock.h"
4 #endif
5
6 #include <linux/percpu-defs.h>
7 #include <linux/lockdep.h>
8
9 typedef struct {
10 #ifdef CONFIG_DEBUG_LOCK_ALLOC
11 struct lockdep_map dep_map;
12 struct task_struct *owner;
13 #endif
14 } local_lock_t;
15
16 #ifdef CONFIG_DEBUG_LOCK_ALLOC
17 # define LL_DEP_MAP_INIT(lockname) \
18 .dep_map = { \
19 .name = #lockname, \
20 .wait_type_inner = LD_WAIT_CONFIG, \
21 }
22 #else
23 # define LL_DEP_MAP_INIT(lockname)
24 #endif
25
26 #define INIT_LOCAL_LOCK(lockname) { LL_DEP_MAP_INIT(lockname) }
27
28 #define __local_lock_init(lock) \
29 do { \
30 static struct lock_class_key __key; \
31 \
32 debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
33 lockdep_init_map_wait(&(lock)->dep_map, #lock, &__key, 0, LD_WAIT_CONFIG);\
34 } while (0)
35
36 #ifdef CONFIG_DEBUG_LOCK_ALLOC
local_lock_acquire(local_lock_t * l)37 static inline void local_lock_acquire(local_lock_t *l)
38 {
39 lock_map_acquire(&l->dep_map);
40 DEBUG_LOCKS_WARN_ON(l->owner);
41 l->owner = current;
42 }
43
local_lock_release(local_lock_t * l)44 static inline void local_lock_release(local_lock_t *l)
45 {
46 DEBUG_LOCKS_WARN_ON(l->owner != current);
47 l->owner = NULL;
48 lock_map_release(&l->dep_map);
49 }
50
51 #else /* CONFIG_DEBUG_LOCK_ALLOC */
local_lock_acquire(local_lock_t * l)52 static inline void local_lock_acquire(local_lock_t *l) { }
local_lock_release(local_lock_t * l)53 static inline void local_lock_release(local_lock_t *l) { }
54 #endif /* !CONFIG_DEBUG_LOCK_ALLOC */
55
56 #define __local_lock(lock) \
57 do { \
58 preempt_disable(); \
59 local_lock_acquire(this_cpu_ptr(lock)); \
60 } while (0)
61
62 #define __local_lock_irq(lock) \
63 do { \
64 local_irq_disable(); \
65 local_lock_acquire(this_cpu_ptr(lock)); \
66 } while (0)
67
68 #define __local_lock_irqsave(lock, flags) \
69 do { \
70 local_irq_save(flags); \
71 local_lock_acquire(this_cpu_ptr(lock)); \
72 } while (0)
73
74 #define __local_unlock(lock) \
75 do { \
76 local_lock_release(this_cpu_ptr(lock)); \
77 preempt_enable(); \
78 } while (0)
79
80 #define __local_unlock_irq(lock) \
81 do { \
82 local_lock_release(this_cpu_ptr(lock)); \
83 local_irq_enable(); \
84 } while (0)
85
86 #define __local_unlock_irqrestore(lock, flags) \
87 do { \
88 local_lock_release(this_cpu_ptr(lock)); \
89 local_irq_restore(flags); \
90 } while (0)
91