1
2
3
4
5
6
7
8
9#ifndef __LINUX_LOCKDEP_H
10#define __LINUX_LOCKDEP_H
11
12struct task_struct;
13struct lockdep_map;
14
15#ifdef CONFIG_LOCKDEP
16
17#include <linux/linkage.h>
18#include <linux/list.h>
19#include <linux/debug_locks.h>
20#include <linux/stacktrace.h>
21
22
23
24
25
26#define XXX_LOCK_USAGE_STATES (1+3*4)
27
28#define MAX_LOCKDEP_SUBCLASSES 8UL
29
30
31
32
33
34
35struct lockdep_subclass_key {
36 char __one_byte;
37} __attribute__ ((__packed__));
38
39struct lock_class_key {
40 struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES];
41};
42
43#define LOCKSTAT_POINTS 4
44
45
46
47
48struct lock_class {
49
50
51
52 struct list_head hash_entry;
53
54
55
56
57 struct list_head lock_entry;
58
59 struct lockdep_subclass_key *key;
60 unsigned int subclass;
61 unsigned int dep_gen_id;
62
63
64
65
66 unsigned long usage_mask;
67 struct stack_trace usage_traces[XXX_LOCK_USAGE_STATES];
68
69
70
71
72
73
74 struct list_head locks_after, locks_before;
75
76
77
78
79
80 unsigned int version;
81
82
83
84
85 unsigned long ops;
86
87 const char *name;
88 int name_version;
89
90#ifdef CONFIG_LOCK_STAT
91 unsigned long contention_point[LOCKSTAT_POINTS];
92 unsigned long contending_point[LOCKSTAT_POINTS];
93#endif
94};
95
96#ifdef CONFIG_LOCK_STAT
97struct lock_time {
98 s64 min;
99 s64 max;
100 s64 total;
101 unsigned long nr;
102};
103
104enum bounce_type {
105 bounce_acquired_write,
106 bounce_acquired_read,
107 bounce_contended_write,
108 bounce_contended_read,
109 nr_bounce_types,
110
111 bounce_acquired = bounce_acquired_write,
112 bounce_contended = bounce_contended_write,
113};
114
115struct lock_class_stats {
116 unsigned long contention_point[4];
117 unsigned long contending_point[4];
118 struct lock_time read_waittime;
119 struct lock_time write_waittime;
120 struct lock_time read_holdtime;
121 struct lock_time write_holdtime;
122 unsigned long bounces[nr_bounce_types];
123};
124
125struct lock_class_stats lock_stats(struct lock_class *class);
126void clear_lock_stats(struct lock_class *class);
127#endif
128
129
130
131
132
133struct lockdep_map {
134 struct lock_class_key *key;
135 struct lock_class *class_cache;
136 const char *name;
137#ifdef CONFIG_LOCK_STAT
138 int cpu;
139 unsigned long ip;
140#endif
141};
142
143
144
145
146
147struct lock_list {
148 struct list_head entry;
149 struct lock_class *class;
150 struct stack_trace trace;
151 int distance;
152};
153
154
155
156
157struct lock_chain {
158 u8 irq_context;
159 u8 depth;
160 u16 base;
161 struct list_head entry;
162 u64 chain_key;
163};
164
165#define MAX_LOCKDEP_KEYS_BITS 13
166
167
168
169
170
171#define MAX_LOCKDEP_KEYS ((1UL << MAX_LOCKDEP_KEYS_BITS) - 1)
172
173struct held_lock {
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 u64 prev_chain_key;
189 unsigned long acquire_ip;
190 struct lockdep_map *instance;
191 struct lockdep_map *nest_lock;
192#ifdef CONFIG_LOCK_STAT
193 u64 waittime_stamp;
194 u64 holdtime_stamp;
195#endif
196 unsigned int class_idx:MAX_LOCKDEP_KEYS_BITS;
197
198
199
200
201
202
203
204
205
206
207
208
209
210 unsigned int irq_context:2;
211 unsigned int trylock:1;
212 unsigned int read:2;
213 unsigned int check:2;
214 unsigned int hardirqs_off:1;
215};
216
217
218
219
220extern void lockdep_init(void);
221extern void lockdep_info(void);
222extern void lockdep_reset(void);
223extern void lockdep_reset_lock(struct lockdep_map *lock);
224extern void lockdep_free_key_range(void *start, unsigned long size);
225extern void lockdep_sys_exit(void);
226
227extern void lockdep_off(void);
228extern void lockdep_on(void);
229
230
231
232
233
234
235
236extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
237 struct lock_class_key *key, int subclass);
238
239
240
241
242
243#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
244 { .name = (_name), .key = (void *)(_key), }
245
246
247
248
249
250
251
252#define lockdep_set_class(lock, key) \
253 lockdep_init_map(&(lock)->dep_map, #key, key, 0)
254#define lockdep_set_class_and_name(lock, key, name) \
255 lockdep_init_map(&(lock)->dep_map, name, key, 0)
256#define lockdep_set_class_and_subclass(lock, key, sub) \
257 lockdep_init_map(&(lock)->dep_map, #key, key, sub)
258#define lockdep_set_subclass(lock, sub) \
259 lockdep_init_map(&(lock)->dep_map, #lock, \
260 (lock)->dep_map.key, sub)
261
262
263
264#define lockdep_match_class(lock, key) lockdep_match_key(&(lock)->dep_map, key)
265
266static inline int lockdep_match_key(struct lockdep_map *lock,
267 struct lock_class_key *key)
268{
269 return lock->key == key;
270}
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
288 int trylock, int read, int check,
289 struct lockdep_map *nest_lock, unsigned long ip);
290
291extern void lock_release(struct lockdep_map *lock, int nested,
292 unsigned long ip);
293
294extern void lock_set_class(struct lockdep_map *lock, const char *name,
295 struct lock_class_key *key, unsigned int subclass,
296 unsigned long ip);
297
298static inline void lock_set_subclass(struct lockdep_map *lock,
299 unsigned int subclass, unsigned long ip)
300{
301 lock_set_class(lock, lock->name, lock->key, subclass, ip);
302}
303
304extern void lockdep_set_current_reclaim_state(gfp_t gfp_mask);
305extern void lockdep_clear_current_reclaim_state(void);
306extern void lockdep_trace_alloc(gfp_t mask);
307
308# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0,
309
310#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
311
312#else
313
314static inline void lockdep_off(void)
315{
316}
317
318static inline void lockdep_on(void)
319{
320}
321
322# define lock_acquire(l, s, t, r, c, n, i) do { } while (0)
323# define lock_release(l, n, i) do { } while (0)
324# define lock_set_class(l, n, k, s, i) do { } while (0)
325# define lock_set_subclass(l, s, i) do { } while (0)
326# define lockdep_set_current_reclaim_state(g) do { } while (0)
327# define lockdep_clear_current_reclaim_state() do { } while (0)
328# define lockdep_trace_alloc(g) do { } while (0)
329# define lockdep_init() do { } while (0)
330# define lockdep_info() do { } while (0)
331# define lockdep_init_map(lock, name, key, sub) \
332 do { (void)(name); (void)(key); } while (0)
333# define lockdep_set_class(lock, key) do { (void)(key); } while (0)
334# define lockdep_set_class_and_name(lock, key, name) \
335 do { (void)(key); (void)(name); } while (0)
336#define lockdep_set_class_and_subclass(lock, key, sub) \
337 do { (void)(key); } while (0)
338#define lockdep_set_subclass(lock, sub) do { } while (0)
339
340
341
342
343
344
345# define INIT_LOCKDEP
346# define lockdep_reset() do { debug_locks = 1; } while (0)
347# define lockdep_free_key_range(start, size) do { } while (0)
348# define lockdep_sys_exit() do { } while (0)
349
350
351
352struct lock_class_key { };
353
354#define lockdep_depth(tsk) (0)
355
356#endif
357
358#ifdef CONFIG_LOCK_STAT
359
360extern void lock_contended(struct lockdep_map *lock, unsigned long ip);
361extern void lock_acquired(struct lockdep_map *lock, unsigned long ip);
362
363#define LOCK_CONTENDED(_lock, try, lock) \
364do { \
365 if (!try(_lock)) { \
366 lock_contended(&(_lock)->dep_map, _RET_IP_); \
367 lock(_lock); \
368 } \
369 lock_acquired(&(_lock)->dep_map, _RET_IP_); \
370} while (0)
371
372#else
373
374#define lock_contended(lockdep_map, ip) do {} while (0)
375#define lock_acquired(lockdep_map, ip) do {} while (0)
376
377#define LOCK_CONTENDED(_lock, try, lock) \
378 lock(_lock)
379
380#endif
381
382#ifdef CONFIG_LOCKDEP
383
384
385
386
387
388
389#define LOCK_CONTENDED_FLAGS(_lock, try, lock, lockfl, flags) \
390 LOCK_CONTENDED((_lock), (try), (lock))
391
392#else
393
394#define LOCK_CONTENDED_FLAGS(_lock, try, lock, lockfl, flags) \
395 lockfl((_lock), (flags))
396
397#endif
398
399#ifdef CONFIG_GENERIC_HARDIRQS
400extern void early_init_irq_lock_class(void);
401#else
402static inline void early_init_irq_lock_class(void)
403{
404}
405#endif
406
407#ifdef CONFIG_TRACE_IRQFLAGS
408extern void early_boot_irqs_off(void);
409extern void early_boot_irqs_on(void);
410extern void print_irqtrace_events(struct task_struct *curr);
411#else
412static inline void early_boot_irqs_off(void)
413{
414}
415static inline void early_boot_irqs_on(void)
416{
417}
418static inline void print_irqtrace_events(struct task_struct *curr)
419{
420}
421#endif
422
423
424
425
426
427
428#define SINGLE_DEPTH_NESTING 1
429
430
431
432
433
434
435#ifdef CONFIG_DEBUG_LOCK_ALLOC
436# ifdef CONFIG_PROVE_LOCKING
437# define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
438# define spin_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i)
439# else
440# define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
441# define spin_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, NULL, i)
442# endif
443# define spin_release(l, n, i) lock_release(l, n, i)
444#else
445# define spin_acquire(l, s, t, i) do { } while (0)
446# define spin_release(l, n, i) do { } while (0)
447#endif
448
449#ifdef CONFIG_DEBUG_LOCK_ALLOC
450# ifdef CONFIG_PROVE_LOCKING
451# define rwlock_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
452# define rwlock_acquire_read(l, s, t, i) lock_acquire(l, s, t, 2, 2, NULL, i)
453# else
454# define rwlock_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
455# define rwlock_acquire_read(l, s, t, i) lock_acquire(l, s, t, 2, 1, NULL, i)
456# endif
457# define rwlock_release(l, n, i) lock_release(l, n, i)
458#else
459# define rwlock_acquire(l, s, t, i) do { } while (0)
460# define rwlock_acquire_read(l, s, t, i) do { } while (0)
461# define rwlock_release(l, n, i) do { } while (0)
462#endif
463
464#ifdef CONFIG_DEBUG_LOCK_ALLOC
465# ifdef CONFIG_PROVE_LOCKING
466# define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
467# else
468# define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
469# endif
470# define mutex_release(l, n, i) lock_release(l, n, i)
471#else
472# define mutex_acquire(l, s, t, i) do { } while (0)
473# define mutex_release(l, n, i) do { } while (0)
474#endif
475
476#ifdef CONFIG_DEBUG_LOCK_ALLOC
477# ifdef CONFIG_PROVE_LOCKING
478# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i)
479# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i)
480# else
481# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i)
482# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i)
483# endif
484# define rwsem_release(l, n, i) lock_release(l, n, i)
485#else
486# define rwsem_acquire(l, s, t, i) do { } while (0)
487# define rwsem_acquire_read(l, s, t, i) do { } while (0)
488# define rwsem_release(l, n, i) do { } while (0)
489#endif
490
491#ifdef CONFIG_DEBUG_LOCK_ALLOC
492# ifdef CONFIG_PROVE_LOCKING
493# define lock_map_acquire(l) lock_acquire(l, 0, 0, 0, 2, NULL, _THIS_IP_)
494# else
495# define lock_map_acquire(l) lock_acquire(l, 0, 0, 0, 1, NULL, _THIS_IP_)
496# endif
497# define lock_map_release(l) lock_release(l, 1, _THIS_IP_)
498#else
499# define lock_map_acquire(l) do { } while (0)
500# define lock_map_release(l) do { } while (0)
501#endif
502
503#ifdef CONFIG_PROVE_LOCKING
504# define might_lock(lock) \
505do { \
506 typecheck(struct lockdep_map *, &(lock)->dep_map); \
507 lock_acquire(&(lock)->dep_map, 0, 0, 0, 2, NULL, _THIS_IP_); \
508 lock_release(&(lock)->dep_map, 0, _THIS_IP_); \
509} while (0)
510# define might_lock_read(lock) \
511do { \
512 typecheck(struct lockdep_map *, &(lock)->dep_map); \
513 lock_acquire(&(lock)->dep_map, 0, 0, 1, 2, NULL, _THIS_IP_); \
514 lock_release(&(lock)->dep_map, 0, _THIS_IP_); \
515} while (0)
516#else
517# define might_lock(lock) do { } while (0)
518# define might_lock_read(lock) do { } while (0)
519#endif
520
521#endif
522