xref: /linux/include/linux/debug_locks.h (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
29a11b49aSIngo Molnar #ifndef __LINUX_DEBUG_LOCKING_H
39a11b49aSIngo Molnar #define __LINUX_DEBUG_LOCKING_H
49a11b49aSIngo Molnar 
560063497SArun Sharma #include <linux/atomic.h>
6*cbcebf5bSSebastian Andrzej Siewior #include <linux/cache.h>
7ca31e146SEduard - Gabriel Munteanu 
89b7f750dSAlexey Dobriyan struct task_struct;
99b7f750dSAlexey Dobriyan 
1001a14bdaSWaiman Long extern int debug_locks __read_mostly;
1101a14bdaSWaiman Long extern int debug_locks_silent __read_mostly;
129a11b49aSIngo Molnar 
139eeba613SFrederic Weisbecker 
__debug_locks_off(void)146eebad1aSPeter Zijlstra static __always_inline int __debug_locks_off(void)
159eeba613SFrederic Weisbecker {
169eeba613SFrederic Weisbecker 	return xchg(&debug_locks, 0);
179eeba613SFrederic Weisbecker }
189eeba613SFrederic Weisbecker 
199a11b49aSIngo Molnar /*
209a11b49aSIngo Molnar  * Generic 'turn off all lock debugging' function:
219a11b49aSIngo Molnar  */
229a11b49aSIngo Molnar extern int debug_locks_off(void);
239a11b49aSIngo Molnar 
249a11b49aSIngo Molnar #define DEBUG_LOCKS_WARN_ON(c)						\
259a11b49aSIngo Molnar ({									\
269a11b49aSIngo Molnar 	int __ret = 0;							\
279a11b49aSIngo Molnar 									\
2853b9d87fSAndrew Morton 	if (!oops_in_progress && unlikely(c)) {				\
2949faa777SPeter Zijlstra 		instrumentation_begin();				\
309127d4b1SIngo Molnar 		if (debug_locks_off() && !debug_locks_silent)		\
312c2fea11SJames Hogan 			WARN(1, "DEBUG_LOCKS_WARN_ON(%s)", #c);		\
3249faa777SPeter Zijlstra 		instrumentation_end();					\
339a11b49aSIngo Molnar 		__ret = 1;						\
349a11b49aSIngo Molnar 	}								\
359a11b49aSIngo Molnar 	__ret;								\
369a11b49aSIngo Molnar })
379a11b49aSIngo Molnar 
389a11b49aSIngo Molnar #ifdef CONFIG_SMP
399a11b49aSIngo Molnar # define SMP_DEBUG_LOCKS_WARN_ON(c)			DEBUG_LOCKS_WARN_ON(c)
409a11b49aSIngo Molnar #else
419a11b49aSIngo Molnar # define SMP_DEBUG_LOCKS_WARN_ON(c)			do { } while (0)
429a11b49aSIngo Molnar #endif
439a11b49aSIngo Molnar 
449a11b49aSIngo Molnar #ifdef CONFIG_DEBUG_LOCKING_API_SELFTESTS
459a11b49aSIngo Molnar   extern void locking_selftest(void);
469a11b49aSIngo Molnar #else
479a11b49aSIngo Molnar # define locking_selftest()	do { } while (0)
489a11b49aSIngo Molnar #endif
499a11b49aSIngo Molnar 
509a11b49aSIngo Molnar #ifdef CONFIG_LOCKDEP
519a11b49aSIngo Molnar extern void debug_show_all_locks(void);
529a11b49aSIngo Molnar extern void debug_show_held_locks(struct task_struct *task);
539a11b49aSIngo Molnar extern void debug_check_no_locks_freed(const void *from, unsigned long len);
541b1d2fb4SColin Cross extern void debug_check_no_locks_held(void);
559a11b49aSIngo Molnar #else
debug_show_all_locks(void)569a11b49aSIngo Molnar static inline void debug_show_all_locks(void)
579a11b49aSIngo Molnar {
589a11b49aSIngo Molnar }
599a11b49aSIngo Molnar 
debug_show_held_locks(struct task_struct * task)609a11b49aSIngo Molnar static inline void debug_show_held_locks(struct task_struct *task)
619a11b49aSIngo Molnar {
629a11b49aSIngo Molnar }
639a11b49aSIngo Molnar 
649a11b49aSIngo Molnar static inline void
debug_check_no_locks_freed(const void * from,unsigned long len)659a11b49aSIngo Molnar debug_check_no_locks_freed(const void *from, unsigned long len)
669a11b49aSIngo Molnar {
679a11b49aSIngo Molnar }
689a11b49aSIngo Molnar 
699a11b49aSIngo Molnar static inline void
debug_check_no_locks_held(void)701b1d2fb4SColin Cross debug_check_no_locks_held(void)
719a11b49aSIngo Molnar {
729a11b49aSIngo Molnar }
739a11b49aSIngo Molnar #endif
749a11b49aSIngo Molnar 
759a11b49aSIngo Molnar #endif
76