| 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 |  | 
|---|