1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __LINUX_DEBUG_LOCKING_H |
3 | #define __LINUX_DEBUG_LOCKING_H |
4 | |
5 | #include <linux/atomic.h> |
6 | #include <linux/cache.h> |
7 | |
8 | struct task_struct; |
9 | |
10 | extern int debug_locks __read_mostly; |
11 | extern int debug_locks_silent __read_mostly; |
12 | |
13 | |
14 | static __always_inline int __debug_locks_off(void) |
15 | { |
16 | return xchg(&debug_locks, 0); |
17 | } |
18 | |
19 | /* |
20 | * Generic 'turn off all lock debugging' function: |
21 | */ |
22 | extern int debug_locks_off(void); |
23 | |
24 | #define DEBUG_LOCKS_WARN_ON(c) \ |
25 | ({ \ |
26 | int __ret = 0; \ |
27 | \ |
28 | if (!oops_in_progress && unlikely(c)) { \ |
29 | instrumentation_begin(); \ |
30 | if (debug_locks_off() && !debug_locks_silent) \ |
31 | WARN(1, "DEBUG_LOCKS_WARN_ON(%s)", #c); \ |
32 | instrumentation_end(); \ |
33 | __ret = 1; \ |
34 | } \ |
35 | __ret; \ |
36 | }) |
37 | |
38 | #ifdef CONFIG_SMP |
39 | # define SMP_DEBUG_LOCKS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c) |
40 | #else |
41 | # define SMP_DEBUG_LOCKS_WARN_ON(c) do { } while (0) |
42 | #endif |
43 | |
44 | #ifdef CONFIG_DEBUG_LOCKING_API_SELFTESTS |
45 | extern void locking_selftest(void); |
46 | #else |
47 | # define locking_selftest() do { } while (0) |
48 | #endif |
49 | |
50 | #ifdef CONFIG_LOCKDEP |
51 | extern void debug_show_all_locks(void); |
52 | extern void debug_show_held_locks(struct task_struct *task); |
53 | extern void debug_check_no_locks_freed(const void *from, unsigned long len); |
54 | extern void debug_check_no_locks_held(void); |
55 | #else |
56 | static inline void debug_show_all_locks(void) |
57 | { |
58 | } |
59 | |
60 | static inline void debug_show_held_locks(struct task_struct *task) |
61 | { |
62 | } |
63 | |
64 | static inline void |
65 | debug_check_no_locks_freed(const void *from, unsigned long len) |
66 | { |
67 | } |
68 | |
69 | static inline void |
70 | debug_check_no_locks_held(void) |
71 | { |
72 | } |
73 | #endif |
74 | |
75 | #endif |
76 | |