Reference
- Measuring Function Duration with Ftrace
- Finding Origins of Latencies Using Ftrace
- Slides: Ftrace
- Slides: Ftrace Kernel Hooks:More than just tracing
介绍
ftrace功能 :帮助了解Linux内核的运行时行为,可以查看系统调用情况,以及某个函数的调用流程。 2.6内核之后引入内核的。以便进行故障调试或性能分析。
Ftrace 跟踪工具由性能分析器(profiler)和跟踪器(tracer)两部分组成,
性能分析器:用来提供追踪数据的解析和图形化作战时(需要 CONFIG_FUNCTION_PROFILER=y)
- 函数性能分析
- 直方图
跟踪器:负责不同追踪事件的实现,数据的来源
- 函数跟踪(function)
- 点跟踪(tracepoint)
- kprobe
- uprobe
- 函数调用关系(function_graph)
- hwlat等
Debugfs提供用户层控制接口
ftrace的目录:/sys/kernel/debug/tracing/ ,常用文件介绍:
- dynamic tracing,动态trace进行过滤的接口,是需要在编译时支持该功能,需要打开对应的宏开关:
- available_events
- available_filter_functions: 可追对函数的完整列表
- available_tracers,当前内核中可用的插件追踪器。
- buffer_size_kb,以KB为单位指定各个CPU追踪缓冲区的大小。系统追踪缓冲区的总大小就是这个值乘以CPU的数量。设置buffer_size_kb时,必须设置current_tracer为nop追踪器。
- buffer_total_size_kb
- current_tracer,通过该接口指定当前ftrace要使用的tracer,也就是要追踪的函数/时间。
- dyn_ftrace_total_info:
- enabled_functions:
- max_graph_depth:
- printk_formats:
- saved_cmdlines:
- saved_cmdlines_size:
- set_event:
- set_event_pid:
- set_ftrace_filter,指定要追踪的函数名称,函数名称仅可以包含一个通配符。
- set_ftrace_notrace,指定不要追踪的函数名称。
- set_ftrace_pid,指定作为追踪对象的进程的PID号。
- set_graph_function:
- set_graph_notrace:
- trace,以文本格式输出内核中追踪缓冲区的内容,是查看trace日志的接口。
- trace_clock:
- trace_marker:
- trace_marker_raw:
- trace_options:
- trace_pipe,与trace相同,但是运行时像管道一样,可以在每次事件发生时读出追踪信息,但是读出的内容不能再次读出
- tracing_cpumask,以十六进制的位掩码指定要作为追踪对象的处理器,例如,指定0xb时仅在处理器0、1、3上进行追踪。
- tracing_on,启用/禁用向追踪缓冲区写入功能。1为启用,0为禁用。
- tracing_thresh:
- uprobe_events:
- uprobe_profile:
支持的tracer包括:
- nop,不执行任何操作。不使用插件追踪器时指定。
- function,函数调用追踪器,可以看出哪个函数何时调用。
- function_graph,函数调用图表追踪器,可以看出哪个函数被哪个函数调用,何时返回。
- mmiotrace,MMIO( Memory MappedI/O)追踪器,用于Nouveau驱动程序等逆向工程。
- blk,block I/O追踪器。
- wakeup,进程调度延迟追踪器。
- wakeup_rt,与wakeup相同,但以实时进程为对象。
- irqsoff,当中断被禁止时,系统无法响应外部事件,造成系统响应延迟,irqsoff跟踪并记录内核中哪些函数禁止了中断,对于其中禁止中断时间最长的,irqsoff将在log文件的第一行标示出来,从而可以迅速定位造成系统响应延迟的原因。
- preemptoff,追踪并记录禁止内核抢占的函数,并清晰显示出禁止内核抢占时间最长的函数。
- preemptirqsoff,追踪并记录禁止内核抢占和中断时间最长的函数
- sched_switch,进行上下文切换的追踪,可以得知从哪个进程切换到了哪个进程。
ftrace有两种主要跟踪机制可以往缓冲区中写数据,一种是函数,一种是事件。前者比较酷,很多教程都会先讲前者。但对我来说,后者才比较可靠实用,所以我先讲后者。
事件是固定插入到内核中的跟踪点,我们看Linux代码的时候,经常看到这种trace_开头的函数调用:
if (likely(prev != next)) {
rq->nr_switches++;
rq->curr = next;
++*switch_count;
trace_sched_switch(preempt, prev, next);
rq = context_switch(rq, prev, next, cookie); /* unlocks the rq */
} else {
lockdep_unpin_lock(&rq->lock, cookie);
raw_spin_unlock_irq(&rq->lock);
}
实验
使用ftrace:分为三步
- 设置tracer类型
- 设置tracer参数
- 使能tracer
内核函数跟踪
cd /sys/kernel/debug/tracing
# Set tracer
echo function > current_tracer
# Set function filter
echo vma_link > set_ftrace_filter
# Enable selected tracer
echo 1 > tracing_on
# See trace result
cat trace
应用的场景不多,只限于想看某几类函数的调用事件。 但是有些场景我们更可能希望获取调用该内核函数的流程(即该函数是在何处被调用), 这需要通过设置 options/func_stack_trace 选项实现。
#先关闭跟踪
echo 0 > tracing_on
# Set tracer
echo function > current_tracer
# Set function filter
echo vma_link > set_ftrace_filter
#开启跟踪函数的调用栈
echo 1 > options/func_stack_trace
# Enable selected tracer
echo 1 > tracing_on
# See trace result
cat trace
如果想要分析内核函数调用的子流程(即本函数调用了哪些子函数,处理的流程如何), 这时需要用到 function_graph 跟踪器,从字面意思就可看出这是函数调用关系跟踪。
echo function_graph > current_tracer
echo *vfs* > set_ftrace_filter
echo 1 > tracing_on
cat trace
事件
可基于 ftrace 跟踪内核静态跟踪点,可跟踪的完整列表可通过 available_events 查看。
高效调试与分析:利用ftrace进行Linux内核追踪 - 知乎
Perf性能分析
Wsl2编译安装Perf
apt工具总是提示找不到,所以就手动编译安装。
git clone https://github.com/microsoft/WSL2-Linux-Kernel --depth 1
cd WSL2-Linux-Kernel/tools/perf
make -j8
sudo cp perf /usr/local/bin