LWN:代码标记以及内存分配追踪!

关注了就能看到更多这么棒的文章哦~

Code tagging and memory-allocation profiling

By Jonathan Corbet
May 31, 2023
LSFMM+BPF
DeepL assisted translation
https://lwn.net/Articles/932402/

去年由 Suren Baghdasaryan 和 Kent Overstreet 提出的代码标记机制(code-tagging mechanism)一直是有密集(有时火药味还很浓)的讨论。在 2023 年的 Linux 存储、文件系统、内存管理和 BPF 峰会上,这些讨论也出现在了内存管理的部分,其开发者(Baghdasaryan 亲自参加,Overstreet 远程参加)试图说服与会者,这个方案的优势足够超过损失。

4f3472dd4ca700bc2dc3c787ab1966ef.png

Baghdasaryan 首先说,code tagging 的使用场景是在进行内存分配分析,对所有内核分配进行统计,从而监测使用情况并发现内存泄漏。他说,在这个领域,任何解决方案都必须要有足够低的性能开销,这样才能在生产系统中使用。它还必须能提供足够多的有用信息;两个目标都要实现可能很困难。所提出的方案包含了两个级别,也就是能提供一个低开销的高级别的信息,并在需要时也能得到具体某些调用位置的详细信息。

提出的实施方案里使用了 code tagging,原理上是将一个 struct 注入到特定的代码位置,从而能识别该位置。可以在这些 tag 上附加一些应用相关字段,可以用于内存分配的分析、缺页跟踪(fault tracking)、延迟记录分析等。有一个专门的宏,用来把 struct 放到一个单独的可执行 section,但也需要一些 inline 代码来把结构和调用关联起来。

他说,这种机制的性能开销,在 slab 分配场景下有 36% 的额外开销,对于 page 分配则是 26%。这看起来很高,但他认为,开发者应该要想到,相关位置的代码都经过是高度优化的。启用内存控制组(memory control groups)所增加的开销就是进行 allocation profiling 所引入开销的十倍了。相关的内存空间开销取决于系统中的 CPU 数量;在一个有大约 10000 个内存分配位置的八核安卓设备上,内存开销大约是 0.3%。

从 Baghdasaryan 问在场的开发者是否会使用这个工具开始,原先准备的讨论内容就已经结束了。

Steve Rostedt 说,有人问他是否有可能用静态调用(static call)来更有效地实现 tagging 工作,因为 static call 可以在运行时的时候加上 patch。他说,目前提出的代码标记功能,是需要在一些宏的外面再包上宏,而且必须要给每个需要分析的接口都明确添加。它要将代码注入到每个调用点,这会导致定位方面和性能方面表现都更差。他建议可以用 objtool 创建一个替代方案,因为 objtool 可以找到一个感兴趣的函数的所有调用位置,并在一个单独的部分为每个函数都创建一个跳转点(trampoline)。该 trampoline 将记录好感兴趣的数据,然后调用目标函数。在正常操作中是不会使用这个 trampoline 的;为了打开 monitor 功能,可以在运行时对调用位置打上 patch,以便跳到 trampoline 位置。

Overstreet 回答说,这个解决方案比起用 magic macro 来说更加难弄(magic)一些;Rostedt 回答说,现在 ftrace 和其他一些功能都是这样工作的,已经经过了很好的测试,可以期待它能正常工作。

Overstreet 说,在源代码中放置标注(annotation)是很有价值的;它允许程序员选择哪些功能被标注出来,并成为文档。code tag 还可以用于 fault injection,例如可以编写一个测试,来覆盖每个调用点的错误处理代码。Rostedt 回答说,所有这些也可以在 trampoline 中完成;甚至可以有一个 BPF hook,这样更加灵活。

John Hubbard 说,36%的开销很高了;最好能让人有办法可以去掉这个开销。他说,他更喜欢像 bpftrace 这样的工具所采取的方法,也就是在运行时附加 probe 探针。Overstreet 说,我们不能在运行时启用 counter 且指望它们有任何意义;Baghdasaryan 补充说,如果在启动时不启用 counter 的话,系统会看到在启用监控前分配的内存出现了释放事件,于是可能搞不清楚了。Rostedt 说,这个问题可以通过在启用 monitor 的情况下来启动系统,然后在收集到所需数据后关闭它,就能解决了。

Overstreet 抱怨说,trampoline 的方案,会导致在开启后带来更大的开销;Rostedt 不同意,他指出,trampoline 将以直接跳转(direct jump)的方式进入,所以不会增加额外的函数调用。随后,双方就细节问题进行了长时间的、有时还是很激烈的讨论,在编者看来这并不值得在此复述了。

Michal Hocko 在讨论结束时指出,这些细节并不是当前的重要问题;开发者需要考虑任何一个工具机制的整体设计,并决定哪种机制最好用。Overstreet 这时说,他想在 struct page 上增加一些 counter,从而收集更多的数据,这个说法对他的方案没有带来任何好处,小组也直接拒绝了这个想法。

会议结束时,似乎没有人对会议的进展感到满意。看起来这注定是一场要持续一段时间的对话。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值