4. ftrace 文件系统结构:/sys/kernel/tracing/ 目录详解
ftrace 通过 tracefs 伪文件系统向用户空间暴露其全部控制与数据接口。挂载点通常为 /sys/kernel/tracing/(旧内核为 /debug/tracing/)。理解该目录下的关键文件,是使用 ftrace 进行内核跟踪与延迟分析的基础。
挂载确认: 执行
mount | grep tracefs 可查看挂载状态。若未挂载,执行 mount -t tracefs tracefs /sys/kernel/tracing/。
4.1 目录全景:核心文件与功能分类
下表列出了 /sys/kernel/tracing/ 下最常用的文件及其作用,按功能分为控制类、配置类与数据输出类。
| 分类 | 文件名 | 作用描述 |
|---|---|---|
| 跟踪器控制 | available_tracers |
列出当前内核支持的所有跟踪器(tracer)名称,如 function、function_graph、blk 等。 |
current_tracer |
读取显示当前激活的跟踪器;写入跟踪器名称可切换跟踪器。 | |
tracing_on |
全局跟踪开关。写入 1 启用跟踪,写入 0 暂停跟踪(不丢失已有数据)。 |
|
| 跟踪配置 | set_ftrace_filter |
设置函数过滤白名单:只跟踪匹配的函数名或通配符模式。 |
set_ftrace_notrace |
设置函数过滤黑名单:排除匹配的函数,不进行跟踪。 | |
| 数据输出 | trace |
以可读文本形式输出当前跟踪缓冲区的内容(循环缓冲,新数据覆盖旧数据)。 |
trace_pipe |
以管道流形式持续输出跟踪数据,读取后数据即被消耗,适合实时监控。 | |
per_cpu/cpuX/trace |
每个 CPU 独立的跟踪缓冲区,可查看指定 CPU 的跟踪数据。 | |
| 缓冲区管理 | buffer_size_kb |
设置每个 CPU 跟踪缓冲区的大小(单位 KB),影响可记录的跟踪事件数量。 |
buffer_total_size_kb |
显示所有 CPU 跟踪缓冲区的总大小。 | |
| 事件跟踪 | events/ |
子目录,包含所有可跟踪的静态事件(tracepoint),如系统调用、调度、IRQ 等。 |
4.2 关键文件详解
4.2.1 available_tracers —— 可用跟踪器清单
该文件列出了当前内核编译时启用的所有跟踪器。常见条目包括:
- function:记录函数调用进入和退出,输出函数名与进程 PID。
- function_graph:以缩进树状图显示函数调用关系,直观展示调用深度与执行时间。
- blk:块设备 I/O 跟踪器,用于分析磁盘请求延迟。
- irqsoff:跟踪中断被关闭的最大时间,用于中断延迟分析。
- preemptoff:跟踪抢占被关闭的最大时间,用于抢占延迟分析。
- wakeup:跟踪高优先级任务从被唤醒到获得 CPU 的调度延迟。
- nop:空跟踪器,不记录任何数据,用于关闭当前跟踪器。
实践建议: 执行
cat /sys/kernel/tracing/available_tracers 查看你的内核支持哪些跟踪器。若缺少 function_graph,可能是内核未配置 CONFIG_FUNCTION_GRAPH_TRACER。
4.2.2 current_tracer —— 当前激活的跟踪器
读取该文件可查看当前正在使用的跟踪器。写入跟踪器名称可立即切换,无需重启系统。
# 查看当前跟踪器
cat /sys/kernel/tracing/current_tracer
# 输出: nop
# 切换到 function_graph 跟踪器
echo function_graph > /sys/kernel/tracing/current_tracer
# 验证切换
cat /sys/kernel/tracing/current_tracer
# 输出: function_graph
注意: 切换跟踪器前,建议先写入
nop 清空状态,避免残留配置影响新跟踪器行为。
4.2.3 trace 与 trace_pipe —— 跟踪数据输出
这两个文件是获取跟踪结果的主要入口,但行为有显著差异:
| 特性 | trace |
trace_pipe |
|---|---|---|
| 读取方式 | 一次性读取当前缓冲区全部内容 | 阻塞式流读取,持续输出新数据 |
| 数据保留 | 读取后数据仍保留在缓冲区(可再次读取) | 读取后数据从缓冲区移除(消费型) |
| 适用场景 | 事后分析、抓取快照 | 实时监控、持续日志采集 |
| 输出格式 | 带时间戳、进程信息、CPU 编号的文本行 | 与 trace 格式相同,但持续追加 |
典型用法对比:
# 使用 trace 抓取一次快照
cat /sys/kernel/tracing/trace
# 使用 trace_pipe 实时监控(Ctrl+C 终止)
cat /sys/kernel/tracing/trace_pipe
4.2.4 tracing_on —— 全局开关
该文件控制跟踪数据的记录是否进行。写入 0 可暂停记录,但不会清空缓冲区;写入 1 恢复记录。这在需要精确控制跟踪起止点时非常有用。
# 暂停跟踪
echo 0 > /sys/kernel/tracing/tracing_on
# 执行待分析的操作
./my_test_program
# 恢复跟踪
echo 1 > /sys/kernel/tracing/tracing_on
# 读取跟踪数据
cat /sys/kernel/tracing/trace
4.3 文件系统结构关系图
下图展示了 /sys/kernel/tracing/ 下核心文件之间的逻辑关系与数据流向:
4.4 典型操作流程
以下是一个完整的 ftrace 使用流程,串联了上述关键文件:
- 确认可用跟踪器:
cat available_tracers - 设置过滤器(可选):
echo 'my_func*' > set_ftrace_filter - 切换跟踪器:
echo function_graph > current_tracer - 启用跟踪:
echo 1 > tracing_on - 执行目标负载: 运行待分析的程序或触发内核路径
- 暂停跟踪:
echo 0 > tracing_on - 读取数据:
cat trace或cat trace_pipe - 恢复为 nop:
echo nop > current_tracer
效率技巧: 使用
trace_pipe 配合 grep 或 awk 进行实时过滤,避免 trace 文件因缓冲区过大而丢失早期数据。例如:cat trace_pipe | grep 'irq'。
4.5 缓冲区管理:buffer_size_kb
默认每个 CPU 的跟踪缓冲区大小通常为 1408 KB(约 1.4 MB)。对于高频函数调用跟踪,该值可能不足,导致早期数据被覆盖。可通过写入新值调整:
# 查看当前每个 CPU 缓冲区大小
cat /sys/kernel/tracing/buffer_size_kb
# 输出: 1408
# 设置为 4096 KB(4 MB)
echo 4096 > /sys/kernel/tracing/buffer_size_kb
# 查看总大小
cat /sys/kernel/tracing/buffer_total_size_kb
# 输出: 40960 (假设 10 个 CPU,每个 4096 KB)
内存注意: 缓冲区大小乘以 CPU 数量即为总占用内存。在 128 核系统上设置 4096 KB 将占用 512 MB 内核内存,请根据系统内存容量合理设置。