目录
1.前言
本文主要是根据阅码场 《Linux内核tracers的实现原理与应用》视频课程在aarch64上的实践。本文主要介绍tracefs的初始化,为后续trace学习做好铺垫。
kernel版本:5.10
平台:arm64
trace fs目录如何建立起来的?
early trace如何开启的?
2. trace_init
void __init trace_init(void)
{
trace_event_init();
}
start_kernel中会调用trace_init
void __init trace_event_init(void)
{
// trace event slab相关操作
event_trace_memsetup();
//ftrace系统调用相关初始化
init_ftrace_syscalls();
//event_trace_enable就是批量化注册trace_event的函数
event_trace_enable();
// trace event初始化域,包括一些trace的公共域,通用域
event_trace_init_fields();
}
trace_init主要就是对trace event的初始化
3. tracefs_init
static int __init tracefs_init(void)
{
int retval;
/* 在/sys/kernel下创建tracing挂载目录 */
retval = sysfs_create_mount_point(kernel_kobj, "tracing");
if (retval)
return -EINVAL;
/* 注册trace fs文件系统 */
retval = register_filesystem(&trace_fs_type);
if (!retval)
tracefs_registered = true;
return retval;
}
core_initcall(tracefs_init);
tracefs的初始化
4. tracer的初始化
//kernel/trace/trace.c
static __init int tracer_init_tracefs(void)
|--trace_access_lock_init()
| //创建/sys/kernel/debug/traing顶级目录
|--tracing_init_dentry();
|--event_trace_init()
|--init_tracer_tracefs(&global_trace, NULL)
|--ftrace_init_tracefs_toplevel(&global_trace, NULL);
| //顶层目录下创建文件
|--trace_create_file("tracing_thresh", 0644, NULL...)
| trace_create_file("README", 0444, NULL,...)
| trace_create_file("saved_cmdlines", 0444, NULL,...)
| trace_create_file("saved_cmdlines_size", 0644, NULL...)
| trace_create_file("saved_tgids", 0444, NULL,...)
|--trace_eval_init()
|--trace_create_eval_file(NULL...)
|--trace_create_file("dyn_ftrace_total_info", 0444, NULL...)
|--create_trace_instances(NULL)
\--update_tracer_options(&global_trace)
初始化阶段将通过fs_initcall(tracer_init_tracefs);来调用tracer_init_tracefs
-
tracing_init_dentry:创建/sys/kernel/debug/traing顶级目录
-
event_trace_init:在顶层目录下创建event相关的一些文件
-
init_tracer_tracefs:在顶层目录下创建一系列tracer公用文件
-
ftrace_init_tracefs_toplevel:顶层目录下创建ftrace相关目录
-
顶层目录下创建其它的文件
|- -event_trace_init
event_trace_init()
|--tracefs_create_file("available_events", 0444, NULL,...)
\--early_event_add_tracer(NULL, tr)
|--create_event_toplevel_files(parent, tr)
| | //创建/sys/kernel/debug/tracing/set_event文件
| |--entry = tracefs_create_file("set_event", 0644, parent, tr, &ftrace_set_event_fops);
| | //创建/sys/kernel/debug/tracing/events目录
| |--d_events = tracefs_create_dir("events", parent);
| | //创建/sys/kernel/debug/tracing/events/enable文件
| |--entry = trace_create_file("enable", 0644, d_events,tr, &ftrace_tr_enable_fops);
| | //创建/sys/kernel/debug/tracing/set_event_pid文件
| |--entry = tracefs_create_file("set_event_pid", 0644, parent, tr, ftrace_set_event_pid_fops);
| | //创建/sys/kernel/debug/tracing/set_event_notrace_pid文件
| |--entry = tracefs_create_file("set_event_notrace_pid", 0644, parent,...)
| |--entry = trace_create_file("header_page", 0444,...)
| |--trace_create_file("header_event", 0444, d_events,...)
| // 为启动早期的event创建目录
|--__trace_early_add_event_dirs(tr)
|--list_for_each_entry(file, &tr->events, list)
event_create_dir(tr->event_dir, file)
event_trace_init:在顶层目录下创建event相关的一些文件
|- -init_tracer_tracefs
init_tracer_tracefs(&global_trace, NULL)
| //创建/sys/kernel/debug/tracing/available_tracers
|--trace_create_file("available_tracers", 0444, d_tracer,...)
| //创建/sys/kernel/debug/tracing/current_tracer
|--trace_create_file("current_tracer", 0644, d_tracer,...)
| //创建/sys/kernel/debug/tracing/tracing_cpumask
|--trace_create_file("tracing_cpumask", 0644, d_tracer,...)
| //创建/sys/kernel/debug/tracing/trace_options
|--trace_create_file("trace_options", 0644, d_tracer,...)
| //创建/sys/kernel/debug/tracing/trace
|--trace_create_file("trace", 0644, d_tracer,...)
| //创建/sys/kernel/debug/tracing/trace_pipe
|--trace_create_file("trace_pipe", 0444, d_tracer...)
| //创建/sys/kernel/debug/tracing/buffer_size_kb
|--trace_create_file("buffer_size_kb", 0644, d_tracer...)
| //创建/sys/kernel/debug/tracing/buffer_total_size_kb
|--trace_create_file("buffer_total_size_kb", 0444, d_tracer...)
| //创建/sys/kernel/debug/tracing/free_buffer
|--trace_create_file("free_buffer", 0200, d_tracer...)
| //创建/sys/kernel/debug/tracing/trace_marker
|--trace_create_file("trace_marker", 0220, d_tracer...)
| //查找ftrace子系统下的名为print的trace_event_file
|--file = __find_event_file(tr, "ftrace", "print");
|...
init_tracer_tracefs:在顶层目录下创建一系列tracer公用文件
|- -ftrace_init_tracefs_toplevel
ftrace_init_tracefs_toplevel(&global_trace, NULL);
|--ftrace_init_dyn_tracefs(d_tracer)
| | //创建/sys/kernel/debug/tracing/available_filter_functions目录
| |--trace_create_file("available_filter_functions", 0444,...)
| | //创建/sys/kernel/debug/tracing/enabled_functions目录
| |--trace_create_file("enabled_functions", 0444...)
| | //创建/sys/kernel/debug/tracing/set_graph_function目录
| |--trace_create_file("set_graph_function", 0644, ,...)
| | //创建/sys/kernel/debug/tracing/set_graph_notrace目录
| |--trace_create_file("set_graph_notrace", 0444,...)
|--ftrace_profile_tracefs(d_tracer)
ftrace_init_tracefs_toplevel:顶层目录下创建ftrace相关目录