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/ 下核心文件之间的逻辑关系与数据流向:

/sys/kernel/tracing/ 核心文件关系与数据流向 available_tracers current_tracer tracing_on set_ftrace_filter set_ftrace_notrace buffer_size_kb ftrace 内核跟踪引擎 (环形缓冲区 · 事件过滤 · 跟踪器调度) trace trace_pipe per_cpu/cpuX/trace 数据流向:控制文件 → 配置跟踪器 → 内核引擎采集 → 输出文件读取 trace 保留数据可重复读;trace_pipe 消费型输出,适合实时管道处理

4.4 典型操作流程

以下是一个完整的 ftrace 使用流程,串联了上述关键文件:

  1. 确认可用跟踪器: cat available_tracers
  2. 设置过滤器(可选): echo 'my_func*' > set_ftrace_filter
  3. 切换跟踪器: echo function_graph > current_tracer
  4. 启用跟踪: echo 1 > tracing_on
  5. 执行目标负载: 运行待分析的程序或触发内核路径
  6. 暂停跟踪: echo 0 > tracing_on
  7. 读取数据: cat trace 或 cat trace_pipe
  8. 恢复为 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 内核内存,请根据系统内存容量合理设置。