xref: /linux-6.15/include/linux/debugobjects.h (revision b778ae25)
13ac7fe5aSThomas Gleixner #ifndef _LINUX_DEBUGOBJECTS_H
23ac7fe5aSThomas Gleixner #define _LINUX_DEBUGOBJECTS_H
33ac7fe5aSThomas Gleixner 
43ac7fe5aSThomas Gleixner #include <linux/list.h>
53ac7fe5aSThomas Gleixner #include <linux/spinlock.h>
63ac7fe5aSThomas Gleixner 
73ac7fe5aSThomas Gleixner enum debug_obj_state {
83ac7fe5aSThomas Gleixner 	ODEBUG_STATE_NONE,
93ac7fe5aSThomas Gleixner 	ODEBUG_STATE_INIT,
103ac7fe5aSThomas Gleixner 	ODEBUG_STATE_INACTIVE,
113ac7fe5aSThomas Gleixner 	ODEBUG_STATE_ACTIVE,
123ac7fe5aSThomas Gleixner 	ODEBUG_STATE_DESTROYED,
133ac7fe5aSThomas Gleixner 	ODEBUG_STATE_NOTAVAILABLE,
143ac7fe5aSThomas Gleixner 	ODEBUG_STATE_MAX,
153ac7fe5aSThomas Gleixner };
163ac7fe5aSThomas Gleixner 
173ac7fe5aSThomas Gleixner struct debug_obj_descr;
183ac7fe5aSThomas Gleixner 
193ac7fe5aSThomas Gleixner /**
203ac7fe5aSThomas Gleixner  * struct debug_obj - representaion of an tracked object
213ac7fe5aSThomas Gleixner  * @node:	hlist node to link the object into the tracker list
223ac7fe5aSThomas Gleixner  * @state:	tracked object state
23a5d8e467SMathieu Desnoyers  * @astate:	current active state
243ac7fe5aSThomas Gleixner  * @object:	pointer to the real object
253ac7fe5aSThomas Gleixner  * @descr:	pointer to an object type specific debug description structure
263ac7fe5aSThomas Gleixner  */
273ac7fe5aSThomas Gleixner struct debug_obj {
283ac7fe5aSThomas Gleixner 	struct hlist_node	node;
293ac7fe5aSThomas Gleixner 	enum debug_obj_state	state;
30a5d8e467SMathieu Desnoyers 	unsigned int		astate;
313ac7fe5aSThomas Gleixner 	void			*object;
323ac7fe5aSThomas Gleixner 	struct debug_obj_descr	*descr;
333ac7fe5aSThomas Gleixner };
343ac7fe5aSThomas Gleixner 
353ac7fe5aSThomas Gleixner /**
363ac7fe5aSThomas Gleixner  * struct debug_obj_descr - object type specific debug description structure
3799777288SStanislaw Gruszka  *
383ac7fe5aSThomas Gleixner  * @name:		name of the object typee
3999777288SStanislaw Gruszka  * @debug_hint:		function returning address, which have associated
4099777288SStanislaw Gruszka  *			kernel symbol, to allow identify the object
413ac7fe5aSThomas Gleixner  * @fixup_init:		fixup function, which is called when the init check
423ac7fe5aSThomas Gleixner  *			fails
433ac7fe5aSThomas Gleixner  * @fixup_activate:	fixup function, which is called when the activate check
443ac7fe5aSThomas Gleixner  *			fails
453ac7fe5aSThomas Gleixner  * @fixup_destroy:	fixup function, which is called when the destroy check
463ac7fe5aSThomas Gleixner  *			fails
473ac7fe5aSThomas Gleixner  * @fixup_free:		fixup function, which is called when the free check
483ac7fe5aSThomas Gleixner  *			fails
49b84d435cSChristine Chan  * @fixup_assert_init:  fixup function, which is called when the assert_init
50b84d435cSChristine Chan  *			check fails
513ac7fe5aSThomas Gleixner  */
523ac7fe5aSThomas Gleixner struct debug_obj_descr {
533ac7fe5aSThomas Gleixner 	const char		*name;
5499777288SStanislaw Gruszka 	void *(*debug_hint)	(void *addr);
553ac7fe5aSThomas Gleixner 	int (*fixup_init)	(void *addr, enum debug_obj_state state);
563ac7fe5aSThomas Gleixner 	int (*fixup_activate)	(void *addr, enum debug_obj_state state);
573ac7fe5aSThomas Gleixner 	int (*fixup_destroy)	(void *addr, enum debug_obj_state state);
583ac7fe5aSThomas Gleixner 	int (*fixup_free)	(void *addr, enum debug_obj_state state);
59b84d435cSChristine Chan 	int (*fixup_assert_init)(void *addr, enum debug_obj_state state);
603ac7fe5aSThomas Gleixner };
613ac7fe5aSThomas Gleixner 
623ac7fe5aSThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS
633ac7fe5aSThomas Gleixner extern void debug_object_init      (void *addr, struct debug_obj_descr *descr);
643ac7fe5aSThomas Gleixner extern void
653ac7fe5aSThomas Gleixner debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr);
66*b778ae25SPaul E. McKenney extern int debug_object_activate  (void *addr, struct debug_obj_descr *descr);
673ac7fe5aSThomas Gleixner extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr);
683ac7fe5aSThomas Gleixner extern void debug_object_destroy   (void *addr, struct debug_obj_descr *descr);
693ac7fe5aSThomas Gleixner extern void debug_object_free      (void *addr, struct debug_obj_descr *descr);
70b84d435cSChristine Chan extern void debug_object_assert_init(void *addr, struct debug_obj_descr *descr);
713ac7fe5aSThomas Gleixner 
72a5d8e467SMathieu Desnoyers /*
73a5d8e467SMathieu Desnoyers  * Active state:
74a5d8e467SMathieu Desnoyers  * - Set at 0 upon initialization.
75a5d8e467SMathieu Desnoyers  * - Must return to 0 before deactivation.
76a5d8e467SMathieu Desnoyers  */
77a5d8e467SMathieu Desnoyers extern void
78a5d8e467SMathieu Desnoyers debug_object_active_state(void *addr, struct debug_obj_descr *descr,
79a5d8e467SMathieu Desnoyers 			  unsigned int expect, unsigned int next);
80a5d8e467SMathieu Desnoyers 
813ac7fe5aSThomas Gleixner extern void debug_objects_early_init(void);
823ac7fe5aSThomas Gleixner extern void debug_objects_mem_init(void);
833ac7fe5aSThomas Gleixner #else
843ac7fe5aSThomas Gleixner static inline void
853ac7fe5aSThomas Gleixner debug_object_init      (void *addr, struct debug_obj_descr *descr) { }
863ac7fe5aSThomas Gleixner static inline void
873ac7fe5aSThomas Gleixner debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr) { }
88*b778ae25SPaul E. McKenney static inline int
89*b778ae25SPaul E. McKenney debug_object_activate  (void *addr, struct debug_obj_descr *descr) { return 0; }
903ac7fe5aSThomas Gleixner static inline void
913ac7fe5aSThomas Gleixner debug_object_deactivate(void *addr, struct debug_obj_descr *descr) { }
923ac7fe5aSThomas Gleixner static inline void
933ac7fe5aSThomas Gleixner debug_object_destroy   (void *addr, struct debug_obj_descr *descr) { }
943ac7fe5aSThomas Gleixner static inline void
953ac7fe5aSThomas Gleixner debug_object_free      (void *addr, struct debug_obj_descr *descr) { }
96b84d435cSChristine Chan static inline void
97b84d435cSChristine Chan debug_object_assert_init(void *addr, struct debug_obj_descr *descr) { }
983ac7fe5aSThomas Gleixner 
993ac7fe5aSThomas Gleixner static inline void debug_objects_early_init(void) { }
1003ac7fe5aSThomas Gleixner static inline void debug_objects_mem_init(void) { }
1013ac7fe5aSThomas Gleixner #endif
1023ac7fe5aSThomas Gleixner 
1033ac7fe5aSThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS_FREE
1043ac7fe5aSThomas Gleixner extern void debug_check_no_obj_freed(const void *address, unsigned long size);
1053ac7fe5aSThomas Gleixner #else
1063ac7fe5aSThomas Gleixner static inline void
1073ac7fe5aSThomas Gleixner debug_check_no_obj_freed(const void *address, unsigned long size) { }
1083ac7fe5aSThomas Gleixner #endif
1093ac7fe5aSThomas Gleixner 
1103ac7fe5aSThomas Gleixner #endif
111