ftrace是什么?

ftrace最初是指function trace,目前已经演变成一种调试框架,可以实现多种trace。

ftrace有啥用?

帮助开发人员了解Linux内核的运行时行为,以便进行故障调试或性能分析。
使用-fpatchable-function-entry编译选项在编译阶段插入nop指令,实现运行时函数替换功能。
支持跟踪进程唤醒wakeup、进程调度sched_switch、关闭中断irqsoff、禁止抢占preemptoff等。

ftrace怎么用?

ftrace跟踪器包含function、function_graph、preemptoff、irqsoff、wakeup等,内核需要打开以下配置:

CONFIG_FUNCTION_TRACER
CONFIG_FUNCTION_GRAPH_TRACER
CONFIG_PREEMPT_TRACER
CONFIG_IRQSOFF_TRACERS
CONFIG_SCHED_TRACER

通过修改/sys/kernel/debug/tracing/current_tracer设置跟踪器,写入nop可以重置跟踪器,
通过修改/sys/kernel/debug/tracing/tracing_on启动或者关闭跟踪,
通过读取/sys/kernel/debug/tracing/trace或者/sys/kernel/debug/tracing/trace_pipe获取跟踪数据。

1.function tracer用于跟踪函数调用,可以调试分析问题或者了解内核运行过程。

root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo > /sys/kernel/debug/tracing/set_ftrace_filter
root@linux:/home/loongson# echo function > /sys/kernel/debug/tracing/current_tracer
root@linux:/home/loongson# echo blk_update_request > /sys/kernel/debug/tracing/set_ftrace_filter
root@linux:/home/loongson# echo 1 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# cat /sys/kernel/debug/tracing/trace
# tracer: function
#
# entries-in-buffer/entries-written: 531/531   #P:4
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
              mv-6969  [001] d.h.  2120.050504: blk_update_request <-blk_mq_end_request
              mv-6973  [001] d.h.  2120.059758: blk_update_request <-blk_mq_end_request
              mv-6981  [001] d.h.  2120.216895: blk_update_request <-blk_mq_end_request
              mv-6985  [001] d.h.  2120.224842: blk_update_request <-blk_mq_end_request
              sh-6988  [001] d.h.  2120.228618: blk_update_request <-blk_mq_end_request
              ar-6993  [001] d.h.  2120.231616: blk_update_request <-blk_mq_end_request
              sh-6991  [001] d.h.  2120.231886: blk_update_request <-blk_mq_end_request
              mv-7001  [001] d.h.  2120.552628: blk_update_request <-blk_mq_end_request
              mv-7005  [001] d.h.  2120.559877: blk_update_request <-blk_mq_end_request
             cc1-6940  [003] d.h.  2120.569537: blk_update_request <-scsi_end_request
              as-7010  [002] d.h.  2120.569765: blk_update_request <-blk_mq_end_request
             cc1-6997  [000] d.h.  2121.089849: blk_update_request <-blk_mq_end_request
 jbd2/nvme0n1p3--116   [003] d.h.  2121.090275: blk_update_request <-blk_mq_end_request
 jbd2/nvme0n1p3--116   [003] d.h.  2121.090282: blk_update_request <-blk_mq_end_request

2.function_graph tracer可以跟踪函数的调用关系。

root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo > /sys/kernel/debug/tracing/set_graph_function
root@linux:/home/loongson# echo function_graph > /sys/kernel/debug/tracing/current_tracer
root@linux:/home/loongson# echo blk_update_request > /sys/kernel/debug/tracing/set_graph_function
root@linux:/home/loongson# echo 1 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# cat /sys/kernel/debug/tracing/trace

3.preemptoff tracer跟踪禁用抢占时的最大延迟,有助于发现导致较大延迟的代码。
禁用抢占时,可以接收到中断,但是任务不能被抢占,一个高优先级的任务必须等待抢占再次启用才能抢占一个低优先级的任务。

root@linux:/home/loongson# echo preemptoff > /sys/kernel/debug/tracing/current_tracer
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
root@linux:/home/loongson# echo 1 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# cat /sys/kernel/debug/tracing/trace

4.irqsoff tracer跟踪禁用中断时的最大延迟,禁用中断时,CPU无法响应外部事件,

root@linux:/home/loongson# echo irqsoff > /sys/kernel/debug/tracing/current_tracer
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
root@linux:/home/loongson# echo 1 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# cat /sys/kernel/debug/tracing/trace

5.wakeup tracer跟踪进程唤醒操作所花费的时间。

root@linux:/home/loongson# echo wakeup > /sys/kernel/debug/tracing/current_tracer
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
root@linux:/home/loongson# echo 1 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# echo 0 > /sys/kernel/debug/tracing/tracing_on
root@linux:/home/loongson# cat /sys/kernel/debug/tracing/trace