ftrace-概述
- 性能工具
- 2024-08-27
- 183热度
- 0评论
ftrace是一个内部跟踪器,用于帮助开发人员查找内核正在发生的事情,它可用于调试或分析用户空间之外发生的延迟和性能问题。ftrace从名称上看是function trace,函数跟踪器,但它实际并不限制函数跟踪,而是多个不同跟踪实用程序的框架。延迟跟踪可以检查在禁用和启用中断之间发生的情况,以及抢占和从唤醒任务到实际运行任务的时间。
ftrace最常见的用途之一是用于事件跟踪(event tracing),整个内核有数百个静态事件点,可以通过tracefs文件系统启用这些事件点,以查看内核某些部分正在发生的事件。
ftrace使用tracefs文件系统来保存控制文件以及显示输出的文件,当tracefs配置到内核中时,将创建目录/sys/kernel/tracing。要挂载此目录,可以将其添加到/etc/fstab文件中。
tracefs /sys/kernel/tracing tracefs defaults 0 0
当然也可以进行命令挂载:mount -t tracefs nodev /sys/kernel/tracing。需要注意的是在4.1内核之前,所有的ftrace跟踪控制文件都在debugfs文件系统中,该文件系统位于/sys/kernel/debug/tracing,因此为了向后兼容,在挂载debugfs文件系统时,tracefs就会自动挂载/sys/kernel/debug/tracing。
挂载tracefs后,可以访问ftrace的控制和输出文件,以下是关键文件节点:
- current_tracer:用于设置或显示当前配置的跟踪器,更改当前跟踪器会清除环形缓冲区内容。
- available_tracers:保存已经编译到内核中的不同类型跟踪器,该类型用于配置上面的current_tracer。
- tracing_on:用于设置是否开启对跟踪环形缓冲区的写入(0/1启停),需要注意的时即使禁止环形缓冲区的写入,跟踪开销可能仍然在发生。每次写current_tracer后,tracing_on会默认设置0。
- trace_options:用于控制trace输出文件的显示数据量,还可以更改堆栈跟踪、时间戳等。
- options:这是一个目录,包含每个可用跟踪选项的文件,也可以通过具有选项名称的
- set_ftrace_filter:用于dynamic ftrace,代码被动态修改(text重写)以禁用对函数分析器(mcount)的调用,这样就可以在几乎不影响性能的情况下配置跟踪。设置函数跟踪过滤后,跟踪器就只会跟踪设置的函数。
- set_ftrace_notrace:与set_ftrace_filter相反,添加的函数不会被跟踪。
- set_ftrace_pid:函数跟踪器只跟踪PID列再次文件中的线程。如果设置了”function-fork”选项,则当PID列在此文件中的任务分叉时,子任务的PID将自动添加到此文件中,并且函数跟踪器也会跟踪子任务。
- set_event_pid:让event只跟踪PID列在此文件的任务。
- set_graph_function:此文件中列出的函数将导致函数图跟踪器仅跟踪这些函数及其调用的函数。需要注意的时set_ftrace_filter/set_ftrace_notrace仍然会影响正在跟踪的函数,即function tracer和graph tracer叠加。
- available_filter_functions:列出ftrace已处理并可以跟踪的函数。即上面set_ftrace_filter/set_graph_function设置的函数名称。
tracers
列出当前常用的跟踪器,可以通过cat available_tracers获取当前支持那些跟踪器。
- function:函数调用跟踪器,用于跟踪所有内核函数。
- function_graph:与函数跟踪器类似,不同之处在于函数跟踪器在函数入口出探测函数,而函数图跟踪器在函数入口和出口处跟踪进行跟踪,然后,它能够绘制类似C代码的函数调用图。
- blk:块跟踪器,blktrace应用程序使用的跟踪器。
- hwlat:硬件延迟跟踪器,用于检测硬件是否产生任何延迟。
- irqsoff:跟踪禁用中断区域并保存最大延迟最长的跟踪。当中断被禁止时,系统无法响应外部事件,比如鼠标和键盘,时钟也无法产生tick中断,这也意味着系统响应延迟,irqsoff这个tracer能够跟踪并记录内核中哪些函数禁止了中断,对于其中中断禁止时间最长的,irqsoff将在Log文件中第一行标记出来,从而使开发者可以迅速定位造成响应延迟的罪魁祸首
- preemptoff:与irqsoff类型,但跟踪并记录禁用抢占的时间量。
- preemptirqsoff:与irqsoff和preemptoff类似,但跟踪并记录禁用irqs或抢占的最大时间。
- wakeup:跟踪并记录在唤醒最高优先级任务后对其进展调度所需要的最大延迟。
- wakeup_rt:跟踪并记录仅RT任务所需要的最大延迟。
- wakeup_dl:跟踪并记录SCHED_DEADLINE任务所需的最大延迟。
- nop:不跟踪任务内容。
tracers输出示例
以下是使用tracer的典型示例,输出格式如下
上面是一个function tracer的输出示例,打印的标题包含跟踪器的名称。在本例中,tracer是function,entries-in-buffer表示缓冲区的事件数,entries-written是写入的数目,差异是由于缓冲区填满而丢失的数据。标题解释了event内容。第一行内容表示Task 为bash,PID为1977,运作在CPU0上,运行的时间戳格式为
下面是irqsoff tracer的示例,输出格式如下:
上图表示tracer是irqsoff,给出了irqsoff latency trace的版本为v1.1.5运行待3.8.0内核上。跟踪的条目和总数均为4个,最大的延时是259us。VP,KP,SP,HP始终为0用于后续使用,#P表示当前在线的CPU数量。task是延迟发生时正在运行的进程。导致延迟最大的启动和停止函数(分别禁用和启动中断的函数)是__lock_task_sighand(关中断)和_raw_spin_unlock_irqrestore(开中断)。
下面接着再来解释一条trace的内容。
- cmd:跟踪中进程的名称
- pid:该进程的pid
- CPU#:进程正在运行的CPU
- irq-soff: “d”表示中断被禁用,否则为 “.”。如果架构不支持irq标志变量,这里为打印“X”。
- need-resched: “N”表示TIF_NEED_RESCHED和“PREEMPT_NEED_RESCHED”都设置了。“n”仅设置了TIF_NEED_RESCHED,“p”仅设置了PREEMPT_NEED_RESCHED。否则为“.”。
- hardirq/softirq:当前是否发生硬件中断、软件中断,“Z”表示NMI发生在hardirq中,“z”表示NMI正在运行,“H”硬件中断发生在软中断中。“h”硬件中断正在运行,“s”软解中断正在运行。“.”正常的上下文。
- preempt-depth: 被抢占的调用深度。
- time:相对于tracer开始的时间戳,这里是相对时间,表示tracer过程中中断被关闭的时间。
- delay:延时的标号,“$”表示大于1S,“@”表示大于100ms,“*”表示大于10ms,“#”表示大于1000us,“!”表示大于100us,“+”表示大于10us,“ ”表示小于等于10us。
trace_options
trace_options文件用户控制trace输出的打印内容,或者控制trace。要查看可用的内容,可以使用cat trace_opstions。
如果要禁用其中一个选项,可以在选项的加上前缀no,如要禁用print-parent,echo noprint-parent > trace_options。如果要重新使能去掉no前缀再写入即可。
- print-parent:在珊瑚跟踪过程中,显示调用函数以及被跟踪的函数。
- sys-offset:不仅显示函数名称,还要显示函数中的偏移量。
- sym-addr:显示函数地址以及函数名称。
- irq-info:显示中断、抢占技术、调度的数据。
- function-trace:默认启用,表示延迟跟踪器将启用函数跟踪,当禁用此选项是,延迟跟踪器不会跟踪函数。
- function-fork:跟踪任务的子任务。
- display-gragh:设置后,延迟跟踪器(irqsoff,wakeup等)将使用函数图跟踪而不是函数跟踪。
- stacktrace:设置后,在记录任何跟踪事件都会记录堆栈跟踪。
由于function_graph tracer输出略不同,因此它有自己的选项来控制显示内容,在options/目录下。
- funcgraph-cpu:设置后,将显示跟踪发生的CPU编号。
- funcgragh-irqs:禁用后,不会跟踪中断内部发生的函数。