Linux源码 debug_objects_early_init debug_objects_mem_init

阅读数:268 评论数:0

跳转到新版页面

分类

Linux

正文

函数在文件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);
};




相关推荐

一、概述 1、为什么Linus不使用GPLv3 在 PC 上,只要你得到了某个程序的源代码,就可以自行编译生成二进制程序,然后替换掉原有的二进制程序,你的程序自由很容易得到保证。然而 iPod、iPh

说明:这种方式只是用于方便阅读代码,因为可以在源代间快速索引跳跃。但是最后可能会有一些warning,可以不必关心,如果是强迫症,可以使用下面这种方式来去掉。

一、概述 在Linux系统中,/usr/bin和/usr/local/bin是两个常见的目录,用于存放可执行文件(二进制文件)。 很多应用都安装在/usr/local下面,先看一下automake工具

  一、概述 vmstat命令是最常见的Linux/Unix监控工具,可以监控给定时间间隔服务器的CPU使用率、内存使用、IO情况。相比top命令,可以查看到整个机器的CPU、内存、IO的使用情况,而

一、概述 sar,System Activity Reporter。是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁

一、简介 简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。 二、使用方法 1、基本语法  awk '条件类型1 {动作1} 条件类型2{动作2} ...

一、概述 列出目标目录中所有的子目录和文件。 二、 语法 ls [选项] [目录名] -a, –all 列出目录下的所有文件,包括以 . 开头的隐含文件 -A 同-a,但不列出“.”(表示当前目录)

一、概述 cd全称是change directory,用于切换当前工作目录。 注意的是,cd命令是一个内建命令,它是由 shell 提供的。因此,不同的 shell 可能会有一些差异,但基本的用法和功

一、概述 全称为print working directory,查看”当前工作目录“的完整路径,一般情况下不带任何参数 二、语法 pwd [选项] -L 即logical,逻辑路径 -P 即

一、概述 通过 mkdir 命令可以实现在指定位置创建以 DirName(指定的文件名)命名的文件夹或目录。要创建文件夹或目录的用户必须对所创建的文件夹的父文件夹具有写权限。并且,所创建的文件夹(目录