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 struct task_struct; 51 52 #ifdef CONFIG_LOCKDEP 53 extern void debug_show_all_locks(void); 54 extern void debug_show_held_locks(struct task_struct *task); 55 extern void debug_check_no_locks_freed(const void *from, unsigned long len); 56 extern void debug_check_no_locks_held(void); 57 #else 58 static inline void debug_show_all_locks(void) 59 { 60 } 61 62 static inline void debug_show_held_locks(struct task_struct *task) 63 { 64 } 65 66 static inline void 67 debug_check_no_locks_freed(const void *from, unsigned long len) 68 { 69 } 70 71 static inline void 72 debug_check_no_locks_held(void) 73 { 74 } 75 #endif 76 77 #endif 78