我正在调查我的 Ubuntu 22.04.2 LTS 机器上的性能问题。我采取以下步骤:
sudo perf record -g -F max -s --call-graph dwarf -e cycles -e sched:sched_switch --switch-events --sample-cpu
然后使用以下命令打开录音sudo hotspot
:
我意识到这个测量结果可能不太准确,因为它在 2 秒内仅收集了 719 个样本。但是...
时间线表明 CPU 在进程 #0 上花费了相当多的时间,我假设这是内核。
当我们查看 HotSpot 中的自上而下视图时,我们可以看到它nft_pipapo_avx2_scratch_index
几乎出现在所有地方。
阅读有关这个东西的内容,它似乎是 netfilter 项目 nf_tables 的一部分:
/* PIPAPO: PIle PAcket POlicies: set for arbitrary concatenations of ranges
定义如下:https://elixir.bootlin.com/linux/latest/source/net/netfilter/nft_set_pipapo_avx2.c#L75
这似乎是一个内核模块,用于处理过滤 IP 数据包和执行防火墙操作。
这似乎并不是那么糟糕,但是当我运行我自己的高性能软件包(相同的perf
命令,但最后添加了我的二进制文件)时,我在最新版本的 HotSpot 中得到了这个:
现在 HotSpot 声称 30% 的“周期”与这个神秘函数相对应。时间轴上的所有蓝色都表明该函数确实在所有线程中都存在。
现在,正如它仍然暗示的那样,这发生在名为的二进制文件中nf_tables
。有趣的是:我在将内核模块列入黑名单后记录了这一点nf_tables
,x_tables
并且ip_tables
。重启后,我确认查询时不存在此类内核模块lsmod
。
当我尝试在 中打开相同的 perf 记录时,情况变得更加困难perf-report
。我甚至从未看到过它。这让我相信我实际上缺少一些标志来perf report
告诉它也显示这些标志。到目前为止,我已经安装了带有调试符号的 linux 内核映像并perf
使用 指向它-k
,但这并没有什么区别。无论如何:如果没有这些内核调试符号,HotSpot 如何能够显示它们?
我目前有两个假设:
- 假设 1)
perf report
没有显示这些样本,因为它根据我分析的二进制进行过滤。 - 假设 2)这是 HotSpot 将周期/时间归因于记录样本的一个可视化错误。
答案1
我已经到了无法重现此问题的地步。我认为,按照以下指南安装了带有调试符号的内核映像后,行为发生了变化: https://wiki.ubuntu.com/DebuggingProgramCrash#Non-built-in_debug_symbol_packages_.28.2A-dbgsym.29
之后我安装了Linux内核调试符号:
sudo apt-get update
sudo apt-get install linux-image-$(uname -r)-dbgsym
现在,HotSpot 仍然显示奇怪的nft_pipapo_avx2_scratch_index
。但是,在使用perf
(与原始问题相同的命令)重新录制并在 HotSpot 中重新打开录制后,它实际上起作用了。我现在看到了我期望看到的内容。一大堆奇怪的不相关的 DSO(动态共享对象,例如nf_tables
、iwlwifi.ko
、mac80211.ko
)不再出现:
所以,我现在猜测这是 HotSpot 中的一个错误,或者 perf 没有通过文件正确传达perf.data
实际发生的情况。我不知道为什么在安装调试符号后我必须重新录制。