1154 lines · 28.2 KB · C
RawDownload
/* * Generic infrastructure for lifetime debugging of objects. * * Started by Thomas Gleixner * * Copyright (C) 2008, Thomas Gleixner <tglx@linutronix.de> * * For licencing details see kernel-base/COPYING */ #define pr_fmt(fmt) "ODEBUG: " fmt #include <linux/debugobjects.h>#include <linux/interrupt.h>#include <linux/sched.h>#include <linux/sched/task_stack.h>#include <linux/seq_file.h>#include <linux/debugfs.h>#include <linux/slab.h>#include <linux/hash.h> #define ODEBUG_HASH_BITS	14#define ODEBUG_HASH_SIZE	(1 << ODEBUG_HASH_BITS) #define ODEBUG_POOL_SIZE	1024#define ODEBUG_POOL_MIN_LEVEL	256 #define ODEBUG_CHUNK_SHIFT	PAGE_SHIFT#define ODEBUG_CHUNK_SIZE	(1 << ODEBUG_CHUNK_SHIFT)#define ODEBUG_CHUNK_MASK	(~(ODEBUG_CHUNK_SIZE - 1)) struct debug_bucket {	struct hlist_head	list;	raw_spinlock_t		lock;}; static struct debug_bucket	obj_hash[ODEBUG_HASH_SIZE]; static struct debug_obj		obj_static_pool[ODEBUG_POOL_SIZE] __initdata; static DEFINE_RAW_SPINLOCK(pool_lock); static HLIST_HEAD(obj_pool); static int			obj_pool_min_free = ODEBUG_POOL_SIZE;static int			obj_pool_free = ODEBUG_POOL_SIZE;static int			obj_pool_used;static int			obj_pool_max_used;static struct kmem_cache	*obj_cache; static int			debug_objects_maxchain __read_mostly;static int			debug_objects_fixups __read_mostly;static int			debug_objects_warnings __read_mostly;static int			debug_objects_enabled __read_mostly				= CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT;static int			debug_objects_pool_size __read_mostly				= ODEBUG_POOL_SIZE;static int			debug_objects_pool_min_level __read_mostly				= ODEBUG_POOL_MIN_LEVEL;static struct debug_obj_descr	*descr_test  __read_mostly; /* * Track numbers of kmem_cache_alloc()/free() calls done. */static int			debug_objects_allocated;static int			debug_objects_freed; static void free_obj_work(struct work_struct *work);static DECLARE_WORK(debug_obj_work, free_obj_work); static int __init enable_object_debug(char *str){	debug_objects_enabled = 1;	return 0;} static int __init disable_object_debug(char *str){	debug_objects_enabled = 0;	return 0;} early_param("debug_objects", enable_object_debug);early_param("no_debug_objects", disable_object_debug); static const char *obj_states[ODEBUG_STATE_MAX] = {	[ODEBUG_STATE_NONE]		= "none",	[ODEBUG_STATE_INIT]		= "initialized",	[ODEBUG_STATE_INACTIVE]		= "inactive",	[ODEBUG_STATE_ACTIVE]		= "active",	[ODEBUG_STATE_DESTROYED]	= "destroyed",	[ODEBUG_STATE_NOTAVAILABLE]	= "not available",}; static void fill_pool(void){	gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;	struct debug_obj *new;	unsigned long flags; 	if (likely(obj_pool_free >= debug_objects_pool_min_level))		return; 	if (unlikely(!obj_cache))		return; 	while (obj_pool_free < debug_objects_pool_min_level) { 		new = kmem_cache_zalloc(obj_cache, gfp);		if (!new)			return; 		raw_spin_lock_irqsave(&pool_lock, flags);		hlist_add_head(&new->node, &obj_pool);		debug_objects_allocated++;		obj_pool_free++;		raw_spin_unlock_irqrestore(&pool_lock, flags);	}} /* * Lookup an object in the hash bucket. */static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b){	struct debug_obj *obj;	int cnt = 0; 	hlist_for_each_entry(obj, &b->list, node) {		cnt++;		if (obj->object == addr)			return obj;	}	if (cnt > debug_objects_maxchain)		debug_objects_maxchain = cnt; 	return NULL;} /* * Allocate a new object. If the pool is empty, switch off the debugger. * Must be called with interrupts disabled. */static struct debug_obj *alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr){	struct debug_obj *obj = NULL; 	raw_spin_lock(&pool_lock);	if (obj_pool.first) {		obj	    = hlist_entry(obj_pool.first, typeof(*obj), node); 		obj->object = addr;		obj->descr  = descr;		obj->state  = ODEBUG_STATE_NONE;		obj->astate = 0;		hlist_del(&obj->node); 		hlist_add_head(&obj->node, &b->list); 		obj_pool_used++;		if (obj_pool_used > obj_pool_max_used)			obj_pool_max_used = obj_pool_used; 		obj_pool_free--;		if (obj_pool_free < obj_pool_min_free)			obj_pool_min_free = obj_pool_free;	}	raw_spin_unlock(&pool_lock); 	return obj;} /* * workqueue function to free objects. * * To reduce contention on the global pool_lock, the actual freeing of * debug objects will be delayed if the pool_lock is busy. We also free * the objects in a batch of 4 for each lock/unlock cycle. */#define ODEBUG_FREE_BATCH	4 static void free_obj_work(struct work_struct *work){	struct debug_obj *objs[ODEBUG_FREE_BATCH];	unsigned long flags;	int i; 	if (!raw_spin_trylock_irqsave(&pool_lock, flags))		return;	while (obj_pool_free >= debug_objects_pool_size + ODEBUG_FREE_BATCH) {		for (i = 0; i < ODEBUG_FREE_BATCH; i++) {			objs[i] = hlist_entry(obj_pool.first,					      typeof(*objs[0]), node);			hlist_del(&objs[i]->node);		} 		obj_pool_free -= ODEBUG_FREE_BATCH;		debug_objects_freed += ODEBUG_FREE_BATCH;		/*		 * We release pool_lock across kmem_cache_free() to		 * avoid contention on pool_lock.		 */		raw_spin_unlock_irqrestore(&pool_lock, flags);		for (i = 0; i < ODEBUG_FREE_BATCH; i++)			kmem_cache_free(obj_cache, objs[i]);		if (!raw_spin_trylock_irqsave(&pool_lock, flags))			return;	}	raw_spin_unlock_irqrestore(&pool_lock, flags);} /* * Put the object back into the pool and schedule work to free objects * if necessary. */static void free_object(struct debug_obj *obj){	unsigned long flags;	int sched = 0; 	raw_spin_lock_irqsave(&pool_lock, flags);	/*	 * schedule work when the pool is filled and the cache is	 * initialized:	 */	if (obj_pool_free > debug_objects_pool_size && obj_cache)		sched = 1;	hlist_add_head(&obj->node, &obj_pool);	obj_pool_free++;	obj_pool_used--;	raw_spin_unlock_irqrestore(&pool_lock, flags);	if (sched)		schedule_work(&debug_obj_work);} /* * We run out of memory. That means we probably have tons of objects * allocated. */static void debug_objects_oom(void){	struct debug_bucket *db = obj_hash;	struct hlist_node *tmp;	HLIST_HEAD(freelist);	struct debug_obj *obj;	unsigned long flags;	int i; 	pr_warn("Out of memory. ODEBUG disabled\n"); 	for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {		raw_spin_lock_irqsave(&db->lock, flags);		hlist_move_list(&db->list, &freelist);		raw_spin_unlock_irqrestore(&db->lock, flags); 		/* Now free them */		hlist_for_each_entry_safe(obj, tmp, &freelist, node) {			hlist_del(&obj->node);			free_object(obj);		}	}} /* * We use the pfn of the address for the hash. That way we can check * for freed objects simply by checking the affected bucket. */static struct debug_bucket *get_bucket(unsigned long addr){	unsigned long hash; 	hash = hash_long((addr >> ODEBUG_CHUNK_SHIFT), ODEBUG_HASH_BITS);	return &obj_hash[hash];} static void debug_print_object(struct debug_obj *obj, char *msg){	struct debug_obj_descr *descr = obj->descr;	static int limit; 	if (limit < 5 && descr != descr_test) {		void *hint = descr->debug_hint ?			descr->debug_hint(obj->object) : NULL;		limit++;		WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "				 "object type: %s hint: %pS\n",			msg, obj_states[obj->state], obj->astate,			descr->name, hint);	}	debug_objects_warnings++;} /* * Try to repair the damage, so we have a better chance to get useful * debug output. */static booldebug_object_fixup(bool (*fixup)(void *addr, enum debug_obj_state state),		   void * addr, enum debug_obj_state state){	if (fixup && fixup(addr, state)) {		debug_objects_fixups++;		return true;	}	return false;} static void debug_object_is_on_stack(void *addr, int onstack){	int is_on_stack;	static int limit; 	if (limit > 4)		return; 	is_on_stack = object_is_on_stack(addr);	if (is_on_stack == onstack)		return; 	limit++;	if (is_on_stack)		pr_warn("object is on stack, but not annotated\n");	else		pr_warn("object is not on stack, but annotated\n");	WARN_ON(1);} static void__debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack){	enum debug_obj_state state;	struct debug_bucket *db;	struct debug_obj *obj;	unsigned long flags; 	fill_pool(); 	db = get_bucket((unsigned long) addr); 	raw_spin_lock_irqsave(&db->lock, flags); 	obj = lookup_object(addr, db);	if (!obj) {		obj = alloc_object(addr, db, descr);		if (!obj) {			debug_objects_enabled = 0;			raw_spin_unlock_irqrestore(&db->lock, flags);			debug_objects_oom();			return;		}		debug_object_is_on_stack(addr, onstack);	} 	switch (obj->state) {	case ODEBUG_STATE_NONE:	case ODEBUG_STATE_INIT:	case ODEBUG_STATE_INACTIVE:		obj->state = ODEBUG_STATE_INIT;		break; 	case ODEBUG_STATE_ACTIVE:		debug_print_object(obj, "init");		state = obj->state;		raw_spin_unlock_irqrestore(&db->lock, flags);		debug_object_fixup(descr->fixup_init, addr, state);		return; 	case ODEBUG_STATE_DESTROYED:		debug_print_object(obj, "init");		break;	default:		break;	} 	raw_spin_unlock_irqrestore(&db->lock, flags);} /** * debug_object_init - debug checks when an object is initialized * @addr:	address of the object * @descr:	pointer to an object specific debug description structure */void debug_object_init(void *addr, struct debug_obj_descr *descr){	if (!debug_objects_enabled)		return; 	__debug_object_init(addr, descr, 0);}EXPORT_SYMBOL_GPL(debug_object_init); /** * debug_object_init_on_stack - debug checks when an object on stack is *				initialized * @addr:	address of the object * @descr:	pointer to an object specific debug description structure */void debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr){	if (!debug_objects_enabled)		return; 	__debug_object_init(addr, descr, 1);}EXPORT_SYMBOL_GPL(debug_object_init_on_stack); /** * debug_object_activate - debug checks when an object is activated * @addr:	address of the object * @descr:	pointer to an object specific debug description structure * Returns 0 for success, -EINVAL for check failed. */int debug_object_activate(void *addr, struct debug_obj_descr *descr){	enum debug_obj_state state;	struct debug_bucket *db;	struct debug_obj *obj;	unsigned long flags;	int ret;	struct debug_obj o = { .object = addr,			       .state = ODEBUG_STATE_NOTAVAILABLE,			       .descr = descr }; 	if (!debug_objects_enabled)		return 0; 	db = get_bucket((unsigned long) addr); 	raw_spin_lock_irqsave(&db->lock, flags); 	obj = lookup_object(addr, db);	if (obj) {		switch (obj->state) {		case ODEBUG_STATE_INIT:		case ODEBUG_STATE_INACTIVE:			obj->state = ODEBUG_STATE_ACTIVE;			ret = 0;			break; 		case ODEBUG_STATE_ACTIVE:			debug_print_object(obj, "activate");			state = obj->state;			raw_spin_unlock_irqrestore(&db->lock, flags);			ret = debug_object_fixup(descr->fixup_activate, addr, state);			return ret ? 0 : -EINVAL; 		case ODEBUG_STATE_DESTROYED:			debug_print_object(obj, "activate");			ret = -EINVAL;			break;		default:			ret = 0;			break;		}		raw_spin_unlock_irqrestore(&db->lock, flags);		return ret;	} 	raw_spin_unlock_irqrestore(&db->lock, flags);	/*	 * We are here when a static object is activated. We	 * let the type specific code confirm whether this is	 * true or not. if true, we just make sure that the	 * static object is tracked in the object tracker. If	 * not, this must be a bug, so we try to fix it up.	 */	if (descr->is_static_object && descr->is_static_object(addr)) {		/* track this static object */		debug_object_init(addr, descr);		debug_object_activate(addr, descr);	} else {		debug_print_object(&o, "activate");		ret = debug_object_fixup(descr->fixup_activate, addr,					ODEBUG_STATE_NOTAVAILABLE);		return ret ? 0 : -EINVAL;	}	return 0;}EXPORT_SYMBOL_GPL(debug_object_activate); /** * debug_object_deactivate - debug checks when an object is deactivated * @addr:	address of the object * @descr:	pointer to an object specific debug description structure */void debug_object_deactivate(void *addr, struct debug_obj_descr *descr){	struct debug_bucket *db;	struct debug_obj *obj;	unsigned long flags; 	if (!debug_objects_enabled)		return; 	db = get_bucket((unsigned long) addr); 	raw_spin_lock_irqsave(&db->lock, flags); 	obj = lookup_object(addr, db);

Lines 1–500 of 1154.