hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#ifndef __LINUX_SPINLOCK_TYPES_H
#define __LINUX_SPINLOCK_TYPES_H
 
/*
 * include/linux/spinlock_types.h - generic spinlock type definitions
 *                                  and initializers
 *
 * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
 * Released under the General Public License (GPL).
 */
 
#if defined(CONFIG_SMP)
# include <asm/spinlock_types.h>
#else
# include <linux/spinlock_types_up.h>
#endif
 
#include <linux/lockdep_types.h>
 
typedef struct raw_spinlock {
   arch_spinlock_t raw_lock;
#ifdef CONFIG_DEBUG_SPINLOCK
   unsigned int magic, owner_cpu;
   void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
   struct lockdep_map dep_map;
#endif
} raw_spinlock_t;
 
#define SPINLOCK_MAGIC        0xdead4ead
 
#define SPINLOCK_OWNER_INIT    ((void *)-1L)
 
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define RAW_SPIN_DEP_MAP_INIT(lockname)        \
   .dep_map = {                    \
       .name = #lockname,            \
       .wait_type_inner = LD_WAIT_SPIN,    \
   }
# define SPIN_DEP_MAP_INIT(lockname)            \
   .dep_map = {                    \
       .name = #lockname,            \
       .wait_type_inner = LD_WAIT_CONFIG,    \
   }
# define HARD_SPIN_DEP_MAP_INIT(lockname)        \
   .dep_map = {                    \
       .name = #lockname,            \
       .wait_type_inner = LD_WAIT_INV,        \
   }
#else
# define RAW_SPIN_DEP_MAP_INIT(lockname)
# define SPIN_DEP_MAP_INIT(lockname)
# define HARD_SPIN_DEP_MAP_INIT(lockname)
#endif
 
#ifdef CONFIG_DEBUG_SPINLOCK
# define SPIN_DEBUG_INIT(lockname)        \
   .magic = SPINLOCK_MAGIC,        \
   .owner_cpu = -1,            \
   .owner = SPINLOCK_OWNER_INIT,
#else
# define SPIN_DEBUG_INIT(lockname)
#endif
 
#define __RAW_SPIN_LOCK_INITIALIZER(lockname)    \
   {                    \
   .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED,    \
   SPIN_DEBUG_INIT(lockname)        \
   RAW_SPIN_DEP_MAP_INIT(lockname) }
 
#define __RAW_SPIN_LOCK_UNLOCKED(lockname)    \
   (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname)
 
#define DEFINE_RAW_SPINLOCK(x)    raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x)
 
typedef struct spinlock {
   union {
       struct raw_spinlock rlock;
 
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
       struct {
           u8 __padding[LOCK_PADSIZE];
           struct lockdep_map dep_map;
       };
#endif
   };
} spinlock_t;
 
#define ___SPIN_LOCK_INITIALIZER(lockname)    \
   {                    \
   .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED,    \
   SPIN_DEBUG_INIT(lockname)        \
   SPIN_DEP_MAP_INIT(lockname) }
 
#define __SPIN_LOCK_INITIALIZER(lockname) \
   { { .rlock = ___SPIN_LOCK_INITIALIZER(lockname) } }
 
#define __SPIN_LOCK_UNLOCKED(lockname) \
   (spinlock_t) __SPIN_LOCK_INITIALIZER(lockname)
 
#define DEFINE_SPINLOCK(x)    spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
 
#ifdef CONFIG_IRQ_PIPELINE
 
void __bad_spinlock_type(void);
 
#define __RAWLOCK(x) ((struct raw_spinlock *)(x))
 
#define LOCK_ALTERNATIVES(__lock, __base_op, __raw_form, __args...)    \
   do {                                \
       if (__builtin_types_compatible_p(typeof(__lock),    \
                        raw_spinlock_t *))    \
           __raw_form;                    \
       else if (__builtin_types_compatible_p(typeof(__lock),    \
                        hard_spinlock_t *))    \
           hard_ ## __base_op(__RAWLOCK(__lock), ##__args); \
       else if (__builtin_types_compatible_p(typeof(__lock),    \
                        hybrid_spinlock_t *))    \
           hybrid_ ## __base_op(__RAWLOCK(__lock), ##__args); \
       else                            \
           __bad_spinlock_type();                \
   } while (0)
 
#define LOCK_ALTERNATIVES_RET(__lock, __base_op, __raw_form, __args...) \
   ({                                \
       long __ret = 0;                        \
       if (__builtin_types_compatible_p(typeof(__lock),    \
                        raw_spinlock_t *))    \
           __ret = __raw_form;                \
       else if (__builtin_types_compatible_p(typeof(__lock),    \
                        hard_spinlock_t *))    \
           __ret = hard_ ## __base_op(__RAWLOCK(__lock), ##__args); \
       else if (__builtin_types_compatible_p(typeof(__lock),    \
                        hybrid_spinlock_t *))    \
           __ret = hybrid_ ## __base_op(__RAWLOCK(__lock), ##__args); \
       else                            \
           __bad_spinlock_type();                \
       __ret;                            \
   })
 
#define LOCKDEP_ALT_DEPMAP(__lock)                    \
   ({                                \
       struct lockdep_map *__ret;                \
       if (__builtin_types_compatible_p(typeof(&(__lock)->dep_map), \
                        struct phony_lockdep_map *)) \
           __ret = &__RAWLOCK(__lock)->dep_map;        \
       else                            \
           __ret = (struct lockdep_map *)(&(__lock)->dep_map); \
       __ret;                            \
   })
 
#define LOCKDEP_HARD_DEBUG(__lock, __nodebug, __debug)    \
   do {                        \
       if (__builtin_types_compatible_p(typeof(__lock),    \
                       raw_spinlock_t *) ||    \
           irq_pipeline_debug_locking()) {            \
           __debug;            \
       } else {                \
           __nodebug;            \
       }                    \
   } while (0)
 
#define LOCKDEP_HARD_DEBUG_RET(__lock, __nodebug, __debug)    \
   ({                        \
       typeof(__nodebug) __ret;        \
       if (__builtin_types_compatible_p(typeof(__lock),    \
                       raw_spinlock_t *) ||    \
           irq_pipeline_debug_locking()) {            \
           __ret = (__debug);        \
       } else {                \
           __ret = (__nodebug);        \
       }                    \
       __ret;                    \
   })
 
#define __HARD_SPIN_LOCK_INITIALIZER(x)    {            \
       .rlock = {                    \
           .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED,    \
           SPIN_DEBUG_INIT(x)            \
           HARD_SPIN_DEP_MAP_INIT(x)        \
       }                        \
   }
 
#define __HARD_SPIN_LOCK_UNLOCKED(x)    \
   (hard_spinlock_t) __HARD_SPIN_LOCK_INITIALIZER(x)
 
#define DEFINE_HARD_SPINLOCK(x)      hard_spinlock_t x = __HARD_SPIN_LOCK_UNLOCKED(x)
 
#define DECLARE_HARD_SPINLOCK(x)    hard_spinlock_t x
 
/*
 * The presence of a phony depmap is tested by LOCKDEP_ALT_DEPMAP() to
 * locate the real depmap without enumerating every spinlock type
 * which may contain one.
 */
struct phony_lockdep_map { };
 
typedef struct hard_spinlock {
   /* XXX: offset_of(struct hard_spinlock, rlock) == 0 */
   struct raw_spinlock rlock;
   struct phony_lockdep_map dep_map;
} hard_spinlock_t;
 
#define DEFINE_MUTABLE_SPINLOCK(x)    hybrid_spinlock_t x = {    \
       .rlock = __RAW_SPIN_LOCK_UNLOCKED(x),            \
   }
 
#define DECLARE_MUTABLE_SPINLOCK(x)    hybrid_spinlock_t x
 
typedef struct hybrid_spinlock {
   /* XXX: offset_of(struct hybrid_spinlock, rlock) == 0 */
   struct raw_spinlock rlock;
   unsigned long hwflags;
   struct phony_lockdep_map dep_map;
} hybrid_spinlock_t;
 
#else
 
typedef raw_spinlock_t hard_spinlock_t;
 
typedef raw_spinlock_t hybrid_spinlock_t;
 
#define LOCK_ALTERNATIVES(__lock, __base_op, __raw_form, __args...)    \
   __raw_form
 
#define LOCK_ALTERNATIVES_RET(__lock, __base_op, __raw_form, __args...) \
   __raw_form
 
#define LOCKDEP_ALT_DEPMAP(__lock)    (&(__lock)->dep_map)
 
#define LOCKDEP_HARD_DEBUG(__lock, __nondebug, __debug)        do { __debug; } while (0)
 
#define LOCKDEP_HARD_DEBUG_RET(__lock, __nondebug, __debug)    ({ __debug; })
 
#define DEFINE_HARD_SPINLOCK(x)        DEFINE_RAW_SPINLOCK(x)
 
#define DECLARE_HARD_SPINLOCK(x)    raw_spinlock_t x
 
#define DEFINE_MUTABLE_SPINLOCK(x)    DEFINE_RAW_SPINLOCK(x)
 
#define DECLARE_MUTABLE_SPINLOCK(x)    raw_spinlock_t x
 
#define __RAWLOCK(x) (x)
 
#define __HARD_SPIN_LOCK_UNLOCKED(__lock)    __RAW_SPIN_LOCK_UNLOCKED(__lock)
 
#define __HARD_SPIN_LOCK_INITIALIZER(__lock)    __RAW_SPIN_LOCK_UNLOCKED(__lock)
 
#endif    /* CONFIG_IRQ_PIPELINE */
 
#include <linux/rwlock_types.h>
 
#endif /* __LINUX_SPINLOCK_TYPES_H */