函数在文件linux/lib/debugobjects.c中
static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE];
static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata;
/*
* Called during early boot to initialize the hash buckets and link
* the static object pool objects into the poll list. After this call
* the object tracker is fully operational.
*/
void __init debug_objects_early_init(void)
{
int i;
//初始化spin lock
for (i = 0; i < ODEBUG_HASH_SIZE; i++)
raw_spin_lock_init(&obj_hash[i].lock);
//将obj_static_pool数组都挂入obj_pool链表
for (i = 0; i < ODEBUG_POOL_SIZE; i++)
hlist_add_head(&obj_static_pool[i].node, &obj_pool);
}
该函数的作用就是初始化obj_hash(hash锁)、obj_static_pool(静态对象池)这两个全局变量,这两个变量会在调试的时候使用。依赖配置CONFIG_DEBUG_OBJECTS。
start_kernel后面在slab机制创建后,还会有debug初始化操作:
void __init debug_objects_mem_init(void)
{
if (!debug_objects_enabled)
return;
//创建debug_obj的slab高速缓存
obj_cache = kmem_cache_create("debug_objects_cache",sizeof (struct debug_obj), 0,SLAB_DEBUG_OBJECTS, NULL);
//obj_cache创建成功则调用debug_objects_replace_static_objects函数
if (!obj_cache || debug_objects_replace_static_objects()) {
debug_objects_enabled = 0;
if (obj_cache)
kmem_cache_destroy(obj_cache);
pr_warn("out of memory.\n");
} else
debug_objects_selftest(); //debug_obj对象自测
}
static int __init debug_objects_replace_static_objects(void)
{
struct debug_bucket *db = obj_hash;
struct hlist_node *tmp;
struct debug_obj *obj, *new;
HLIST_HEAD(objects);
int i, cnt = 0;
//从高速缓存中分配debug_obj对象挂载到全局链表objects
for (i = 0; i < ODEBUG_POOL_SIZE; i++) {
obj = kmem_cache_zalloc(obj_cache, GFP_KERNEL);
if (!obj)
goto free;
hlist_add_head(&obj->node, &objects);
}
//此时只有一个cpu在运行,关中断即进入临界区。是为了防止lockdep hell of lock ordering
local_irq_disable();
//从obj_pool中移除静态的debug_obj对象
hlist_for_each_entry_safe(obj, tmp, &obj_pool, node)
hlist_del(&obj->node);
//将刚分配的动态debug_obj对象链入obj_pool
hlist_move_list(&objects, &obj_pool);
for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
//将obj_hash中的debug_bucket对象上的list节点挂载的debug_obj对象链入objects链表
hlist_move_list(&db->list, &objects);
//然后遍历objects链表中的debug_obj对象
hlist_for_each_entry(obj, &objects, node) {
//从obj_pool取出一个debug_obj对象
new = hlist_entry(obj_pool.first, typeof(*obj), node);
//将该debug_obj对象从obj_pool链表删除
hlist_del(&new->node);
//拷贝debug_obj对象
*new = *obj;
//将该新debug_obj对象链入到objects链表中的debug_bucket对象上的list节点
hlist_add_head(&new->node, &db->list);
cnt++;
}
}
local_irq_enable();
pr_debug("%d of %d active objects replaced\n",cnt, obj_pool_used);
return 0;
free:
hlist_for_each_entry_safe(obj, tmp, &objects, node) {
hlist_del(&obj->node);
kmem_cache_free(obj_cache, obj);
}
return -ENOMEM;
}
相关结构体
struct debug_bucket {
struct hlist_head list; //挂载的是当前debug_obj对象
raw_spinlock_t lock;
};
struct debug_obj {
struct hlist_node node; //链接跟踪器列表中的对象
enum debug_obj_state state; //跟踪的对象状态
unsigned int astate; //当前active状态
void *object;//对实际对象的指针
struct debug_obj_descr *descr; //用于调试的描述符结构体指针
};
enum debug_obj_state {
ODEBUG_STATE_NONE,
ODEBUG_STATE_INIT,
ODEBUG_STATE_INACTIVE,
ODEBUG_STATE_ACTIVE,
ODEBUG_STATE_DESTROYED,
ODEBUG_STATE_NOTAVAILABLE,
ODEBUG_STATE_MAX,
};
struct debug_obj_descr {
const char *name;
void *(*debug_hint) (void *addr);
int (*fixup_init) (void *addr, enum debug_obj_state state);
int (*fixup_activate) (void *addr, enum debug_obj_state state);
int (*fixup_destroy) (void *addr, enum debug_obj_state state);
int (*fixup_free) (void *addr, enum debug_obj_state state);
int (*fixup_assert_init)(void *addr, enum debug_obj_state state);
};