重置WARN_ONCE
参考
当WARN_ONCE或者WARN_ON_ONCE被第一次触发时,会输出调用栈,后面就不会了。可以使用下面的命令重置,这样再次触发时,还可以输出一次调用栈:
echo 1 > /sys/kernel/debug/clear_warn_once
相关的实现在kernel\panic.c:
/* Support resetting WARN*_ONCE state */
static int clear_warn_once_set(void *data, u64 val)
{
generic_bug_clear_once();
memset(__start_once, 0, __end_once - __start_once);
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(clear_warn_once_fops, NULL, clear_warn_once_set,
"%lld\n");
其中generic_bug_clear_once在lib\bug.c中:
static void clear_once_table(struct bug_entry *start, struct bug_entry *end)
{
struct bug_entry *bug;
for (bug = start; bug < end; bug++)
bug->flags &= ~BUGFLAG_DONE;
}
void generic_bug_clear_once(void)
{
#ifdef CONFIG_MODULES
struct module *mod;
rcu_read_lock_sched();
list_for_each_entry_rcu(mod, &module_bug_list, bug_list)
clear_once_table(mod->bug_table,
mod->bug_table + mod->num_bugs);
rcu_read_unlock_sched();
#endif
clear_once_table(__start___bug_table, __stop___bug_table);
}
在clear_warn_once_set中做了两件事:
-
调用generic_bug_clear_once把模块以及内核自己的所有的bug_entry->flags成员的BUGFLAG_DONE位清除
-
将内核的
*(.data.once)段的内容清0
也就是说,WARN_ON_ONCE或者WARN_ONCE会利用上面两种数据段的内容来判断是否需要输出上下文信息,这个在后面的文章中再分析。
本文来自博客园,作者:dolinux,未经同意,禁止转载

浙公网安备 33010602011771号