这是我认为不可能的另一种能力。调用了哪些内核生物功能?
# ./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