xref: /openbmc/linux/include/linux/debugobjects.h (revision c23c8082)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
23ac7fe5aSThomas Gleixner #ifndef _LINUX_DEBUGOBJECTS_H
33ac7fe5aSThomas Gleixner #define _LINUX_DEBUGOBJECTS_H
43ac7fe5aSThomas Gleixner 
53ac7fe5aSThomas Gleixner #include <linux/list.h>
63ac7fe5aSThomas Gleixner #include <linux/spinlock.h>
73ac7fe5aSThomas Gleixner 
83ac7fe5aSThomas Gleixner enum debug_obj_state {
93ac7fe5aSThomas Gleixner 	ODEBUG_STATE_NONE,
103ac7fe5aSThomas Gleixner 	ODEBUG_STATE_INIT,
113ac7fe5aSThomas Gleixner 	ODEBUG_STATE_INACTIVE,
123ac7fe5aSThomas Gleixner 	ODEBUG_STATE_ACTIVE,
133ac7fe5aSThomas Gleixner 	ODEBUG_STATE_DESTROYED,
143ac7fe5aSThomas Gleixner 	ODEBUG_STATE_NOTAVAILABLE,
153ac7fe5aSThomas Gleixner 	ODEBUG_STATE_MAX,
163ac7fe5aSThomas Gleixner };
173ac7fe5aSThomas Gleixner 
183ac7fe5aSThomas Gleixner struct debug_obj_descr;
193ac7fe5aSThomas Gleixner 
203ac7fe5aSThomas Gleixner /**
21*c23c8082SZhen Lei  * struct debug_obj - representation of an tracked object
223ac7fe5aSThomas Gleixner  * @node:	hlist node to link the object into the tracker list
233ac7fe5aSThomas Gleixner  * @state:	tracked object state
24a5d8e467SMathieu Desnoyers  * @astate:	current active state
253ac7fe5aSThomas Gleixner  * @object:	pointer to the real object
263ac7fe5aSThomas Gleixner  * @descr:	pointer to an object type specific debug description structure
273ac7fe5aSThomas Gleixner  */
283ac7fe5aSThomas Gleixner struct debug_obj {
293ac7fe5aSThomas Gleixner 	struct hlist_node	node;
303ac7fe5aSThomas Gleixner 	enum debug_obj_state	state;
31a5d8e467SMathieu Desnoyers 	unsigned int		astate;
323ac7fe5aSThomas Gleixner 	void			*object;
33aedcade6SStephen Boyd 	const struct debug_obj_descr *descr;
343ac7fe5aSThomas Gleixner };
353ac7fe5aSThomas Gleixner 
363ac7fe5aSThomas Gleixner /**
373ac7fe5aSThomas Gleixner  * struct debug_obj_descr - object type specific debug description structure
3899777288SStanislaw Gruszka  *
393ac7fe5aSThomas Gleixner  * @name:		name of the object typee
4099777288SStanislaw Gruszka  * @debug_hint:		function returning address, which have associated
4199777288SStanislaw Gruszka  *			kernel symbol, to allow identify the object
4217359a80SRandy Dunlap  * @is_static_object:	return true if the obj is static, otherwise return false
433ac7fe5aSThomas Gleixner  * @fixup_init:		fixup function, which is called when the init check
44b1e4d9d8SDu, Changbin  *			fails. All fixup functions must return true if fixup
45b1e4d9d8SDu, Changbin  *			was successful, otherwise return false
463ac7fe5aSThomas Gleixner  * @fixup_activate:	fixup function, which is called when the activate check
473ac7fe5aSThomas Gleixner  *			fails
483ac7fe5aSThomas Gleixner  * @fixup_destroy:	fixup function, which is called when the destroy check
493ac7fe5aSThomas Gleixner  *			fails
503ac7fe5aSThomas Gleixner  * @fixup_free:		fixup function, which is called when the free check
513ac7fe5aSThomas Gleixner  *			fails
52b84d435cSChristine Chan  * @fixup_assert_init:  fixup function, which is called when the assert_init
53b84d435cSChristine Chan  *			check fails
543ac7fe5aSThomas Gleixner  */
553ac7fe5aSThomas Gleixner struct debug_obj_descr {
563ac7fe5aSThomas Gleixner 	const char		*name;
5799777288SStanislaw Gruszka 	void *(*debug_hint)(void *addr);
58b9fdac7fSDu, Changbin 	bool (*is_static_object)(void *addr);
59b1e4d9d8SDu, Changbin 	bool (*fixup_init)(void *addr, enum debug_obj_state state);
60b1e4d9d8SDu, Changbin 	bool (*fixup_activate)(void *addr, enum debug_obj_state state);
61b1e4d9d8SDu, Changbin 	bool (*fixup_destroy)(void *addr, enum debug_obj_state state);
62b1e4d9d8SDu, Changbin 	bool (*fixup_free)(void *addr, enum debug_obj_state state);
63b1e4d9d8SDu, Changbin 	bool (*fixup_assert_init)(void *addr, enum debug_obj_state state);
643ac7fe5aSThomas Gleixner };
653ac7fe5aSThomas Gleixner 
663ac7fe5aSThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS
67aedcade6SStephen Boyd extern void debug_object_init      (void *addr, const struct debug_obj_descr *descr);
683ac7fe5aSThomas Gleixner extern void
69aedcade6SStephen Boyd debug_object_init_on_stack(void *addr, const struct debug_obj_descr *descr);
70aedcade6SStephen Boyd extern int debug_object_activate  (void *addr, const struct debug_obj_descr *descr);
71aedcade6SStephen Boyd extern void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr);
72aedcade6SStephen Boyd extern void debug_object_destroy   (void *addr, const struct debug_obj_descr *descr);
73aedcade6SStephen Boyd extern void debug_object_free      (void *addr, const struct debug_obj_descr *descr);
74aedcade6SStephen Boyd extern void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr);
753ac7fe5aSThomas Gleixner 
76a5d8e467SMathieu Desnoyers /*
77a5d8e467SMathieu Desnoyers  * Active state:
78a5d8e467SMathieu Desnoyers  * - Set at 0 upon initialization.
79a5d8e467SMathieu Desnoyers  * - Must return to 0 before deactivation.
80a5d8e467SMathieu Desnoyers  */
81a5d8e467SMathieu Desnoyers extern void
82aedcade6SStephen Boyd debug_object_active_state(void *addr, const struct debug_obj_descr *descr,
83a5d8e467SMathieu Desnoyers 			  unsigned int expect, unsigned int next);
84a5d8e467SMathieu Desnoyers 
853ac7fe5aSThomas Gleixner extern void debug_objects_early_init(void);
863ac7fe5aSThomas Gleixner extern void debug_objects_mem_init(void);
873ac7fe5aSThomas Gleixner #else
883ac7fe5aSThomas Gleixner static inline void
debug_object_init(void * addr,const struct debug_obj_descr * descr)89aedcade6SStephen Boyd debug_object_init      (void *addr, const struct debug_obj_descr *descr) { }
903ac7fe5aSThomas Gleixner static inline void
debug_object_init_on_stack(void * addr,const struct debug_obj_descr * descr)91aedcade6SStephen Boyd debug_object_init_on_stack(void *addr, const struct debug_obj_descr *descr) { }
92b778ae25SPaul E. McKenney static inline int
debug_object_activate(void * addr,const struct debug_obj_descr * descr)93aedcade6SStephen Boyd debug_object_activate  (void *addr, const struct debug_obj_descr *descr) { return 0; }
943ac7fe5aSThomas Gleixner static inline void
debug_object_deactivate(void * addr,const struct debug_obj_descr * descr)95aedcade6SStephen Boyd debug_object_deactivate(void *addr, const struct debug_obj_descr *descr) { }
963ac7fe5aSThomas Gleixner static inline void
debug_object_destroy(void * addr,const struct debug_obj_descr * descr)97aedcade6SStephen Boyd debug_object_destroy   (void *addr, const struct debug_obj_descr *descr) { }
983ac7fe5aSThomas Gleixner static inline void
debug_object_free(void * addr,const struct debug_obj_descr * descr)99aedcade6SStephen Boyd debug_object_free      (void *addr, const struct debug_obj_descr *descr) { }
100b84d435cSChristine Chan static inline void
debug_object_assert_init(void * addr,const struct debug_obj_descr * descr)101aedcade6SStephen Boyd debug_object_assert_init(void *addr, const struct debug_obj_descr *descr) { }
1023ac7fe5aSThomas Gleixner 
debug_objects_early_init(void)1033ac7fe5aSThomas Gleixner static inline void debug_objects_early_init(void) { }
debug_objects_mem_init(void)1043ac7fe5aSThomas Gleixner static inline void debug_objects_mem_init(void) { }
1053ac7fe5aSThomas Gleixner #endif
1063ac7fe5aSThomas Gleixner 
1073ac7fe5aSThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS_FREE
1083ac7fe5aSThomas Gleixner extern void debug_check_no_obj_freed(const void *address, unsigned long size);
1093ac7fe5aSThomas Gleixner #else
1103ac7fe5aSThomas Gleixner static inline void
debug_check_no_obj_freed(const void * address,unsigned long size)1113ac7fe5aSThomas Gleixner debug_check_no_obj_freed(const void *address, unsigned long size) { }
1123ac7fe5aSThomas Gleixner #endif
1133ac7fe5aSThomas Gleixner 
1143ac7fe5aSThomas Gleixner #endif
115