GNU Linux-libre 5.10.217-gnu1
[releases.git] / include / linux / local_lock_internal.h
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 LOCAL_LOCK_DEBUG_INIT(lockname)                \
18         .dep_map = {                                    \
19                 .name = #lockname,                      \
20                 .wait_type_inner = LD_WAIT_CONFIG,      \
21                 .lock_type = LD_LOCK_PERCPU,            \
22         },                                              \
23         .owner = NULL,
24
25 static inline void local_lock_acquire(local_lock_t *l)
26 {
27         lock_map_acquire(&l->dep_map);
28         DEBUG_LOCKS_WARN_ON(l->owner);
29         l->owner = current;
30 }
31
32 static inline void local_lock_release(local_lock_t *l)
33 {
34         DEBUG_LOCKS_WARN_ON(l->owner != current);
35         l->owner = NULL;
36         lock_map_release(&l->dep_map);
37 }
38
39 static inline void local_lock_debug_init(local_lock_t *l)
40 {
41         l->owner = NULL;
42 }
43 #else /* CONFIG_DEBUG_LOCK_ALLOC */
44 # define LOCAL_LOCK_DEBUG_INIT(lockname)
45 static inline void local_lock_acquire(local_lock_t *l) { }
46 static inline void local_lock_release(local_lock_t *l) { }
47 static inline void local_lock_debug_init(local_lock_t *l) { }
48 #endif /* !CONFIG_DEBUG_LOCK_ALLOC */
49
50 #define INIT_LOCAL_LOCK(lockname)       { LOCAL_LOCK_DEBUG_INIT(lockname) }
51
52 #define __local_lock_init(lock)                                 \
53 do {                                                            \
54         static struct lock_class_key __key;                     \
55                                                                 \
56         debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
57         lockdep_init_map_type(&(lock)->dep_map, #lock, &__key,  \
58                               0, LD_WAIT_CONFIG, LD_WAIT_INV,   \
59                               LD_LOCK_PERCPU);                  \
60         local_lock_debug_init(lock);                            \
61 } while (0)
62
63 #define __local_lock(lock)                                      \
64         do {                                                    \
65                 preempt_disable();                              \
66                 local_lock_acquire(this_cpu_ptr(lock));         \
67         } while (0)
68
69 #define __local_lock_irq(lock)                                  \
70         do {                                                    \
71                 local_irq_disable();                            \
72                 local_lock_acquire(this_cpu_ptr(lock));         \
73         } while (0)
74
75 #define __local_lock_irqsave(lock, flags)                       \
76         do {                                                    \
77                 local_irq_save(flags);                          \
78                 local_lock_acquire(this_cpu_ptr(lock));         \
79         } while (0)
80
81 #define __local_unlock(lock)                                    \
82         do {                                                    \
83                 local_lock_release(this_cpu_ptr(lock));         \
84                 preempt_enable();                               \
85         } while (0)
86
87 #define __local_unlock_irq(lock)                                \
88         do {                                                    \
89                 local_lock_release(this_cpu_ptr(lock));         \
90                 local_irq_enable();                             \
91         } while (0)
92
93 #define __local_unlock_irqrestore(lock, flags)                  \
94         do {                                                    \
95                 local_lock_release(this_cpu_ptr(lock));         \
96                 local_irq_restore(flags);                       \
97         } while (0)