Linux ftrace 函数计数

这是我认为不可能的另一种能力。调用了哪些内核生物功能?

# ./funccount 'bio_*'
Tracing "bio_*"... Ctrl-C to end.
^C
FUNC                              COUNT
bio_attempt_back_merge               26
bio_get_nr_vecs                     361
bio_alloc                           536
bio_alloc_bioset                    536
bio_endio                           536
bio_free                            536
bio_fs_destructor                   536
bio_init                            536
bio_integrity_enabled               536
bio_put                             729
bio_add_page                       1004

伟大的!每秒以“tcp_”开头的前 5 个函数怎么样?

# ./funccount -i 1 -t 5 'tcp_*'
Tracing "tcp_*". Top 5 only... Ctrl-C to end.

FUNC                              COUNT
tcp_cleanup_rbuf                    386
tcp_service_net_dma                 386
tcp_established_options             549
tcp_v4_md5_lookup                   560
tcp_v4_md5_do_lookup                890

FUNC                              COUNT
tcp_service_net_dma                 498
tcp_cleanup_rbuf                    499
tcp_established_options             664
tcp_v4_md5_lookup                   672
tcp_v4_md5_do_lookup               1071

[...]

惊人的!
就像我之前关于perf Hacktograms的帖子一样,此功能也是 SystemTap、ktap 和 DTrace 等高级跟踪器的基础。但我没有使用那些。我什至没有使用 perf_events。
这是在标准 Linux 3.2 内核上使用动态跟踪和按 CPU 的内核聚合。
它使用 ftrace 执行此操作,由我的funccount脚本自动执行。
ftrace 是 Linux 内核的一部分,在编译时包含在各种 FTRACE CONFIG 选项中(包括 CONFIG_DYNAMIC_FTRACE,在我的系统上已经打开)。 您可以通过 /sys/kernel/debug/tracing 下的控制文件对其进行操作。 使用起来有点棘手,但可以完成很多工作。 有关详细信息,请参阅内核源文档 trace/ftrace.txt。
为什么
了解函数调用率可能是调试和性能分析的有用工具。 这也是我在跟踪子系统时使用的常规程序的一部分,尤其是不熟悉的子系统。
动态跟踪是惊人的,但很难知道从哪里开始,尤其是在面对感兴趣的子系统中的数百个函数时。通过计算实际使用的功能,您可以缩小潜在目标。因此,您可以使用 funccount 查找活动函数,然后使用其他跟踪器(包括perf_events 动态跟踪)更详细地探测它们。
识别活动内核函数的另一种方法是基于堆栈跟踪样本创建perf_events CPU 火焰图。我通常会从这个开始,因为相对于采样率,它的开销较低(固定),并且还可以立即解决许多问题。当我深入研究子系统时,我会转向功能计数。
函数计数
这是一个自动化 ftrace 的简单脚本。它只做一件事:核函数计数。

# ./funccount -h
USAGE: funccount [-hT] [-i secs] [-d secs] [-t top] funcstring
                 -d seconds      # total duration of trace
                 -h              # this usage message
                 -i seconds      # interval summary
                 -t top          # show top num entries only
                 -T              # include timestamp (for -i)
  eg,
        funccount 'vfs*'         # trace all funcs that match "vfs*"
        funccount -d 5 'tcp*'    # trace "tcp*" funcs for 5 seconds
        funccount -t 10 'ext3*'  # show top 10 "ext3*" funcs
        funccount -i 1 'ext3*'   # summary every 1 second
        funccount -i 1 -d 5 'ext3*' # 5 x 1 second summaries

我将它添加到我在 github 上的perf-tools集合中。
它通过启用 ftrace 函数分析器来工作。它创建每个 CPU 的摘要(这是有效的 - 更新计数时没有同步开销),funccount 为报告组合了这些摘要。ftrace 已经为其函数过滤器提供了匹配通配符的能力。
并非所有函数都从 ftrace 和 funccount 可见。如果您认为某个函数应该包含在输出中,但缺少,请在 /proc/kallsyms(内核符号)和 /sys/kernel/debug/tracing/available_filter_functions(ftrace 可以跟踪的内容)中检查它。
内核函数的动态跟踪过去在 Linux 上一直存在问题,存在内核恐慌的风险。我没有体验过它们(我已经在 3.2 和 3.16 上运行过这个脚本),但无论如何我想警告你:我会先用一台测试机器(有负载)来试试这个。
感谢 Steven Rostedt 和其他忙于为 ftrace 添加强大功能的人。

转载翻译自: https://www.brendangregg.com