关于修复Linux内核中eBPF自旋锁问题的故事
A tale about fixing eBPF spinlock issues in the Linux kernel

原始链接: https://rovarma.com/articles/a-tale-about-fixing-ebpf-spinlock-issues-in-the-linux-kernel/

## Superluminal 在 Linux 上的调试:深入内核调试 团队在测试 Superluminal(一款 CPU 分析器)的 Linux 版本时,遇到了持续的系统冻结问题。该问题可在运行 Fedora 42(内核 6.17.4-200)的物理机上重现,表现为在性能分析期间的周期性停顿,与较长的 NMI(不可屏蔽中断)处理时间有关。 调试具有挑战性,最初受到无法在虚拟机中重现问题的影响。对 Superluminal 捕获的分析显示,在冻结期间存在可疑的 CPU 活动。根本原因被追溯到内核的弹性队列自旋锁 (rqspinlock) 中的竞争条件,该条件由采样中断和访问环形缓冲区的上下文切换之间的交互触发。 需要进行多次修复,包括调整死锁检测时机以及处理持有锁期间的 NMI。问题源于内核(6.15+)中的一个相对较新的更改,并且不存在于先前开发中使用的旧内核中。这些修复已回移植到内核 6.17 和 6.18 中,并包含在 6.19 中。 此外,还针对旧内核实施了一个临时解决方法。 此次经历凸显了内核级调试的复杂性以及及时更新内核的重要性。

## Linux内核eBPF自旋锁问题 - 摘要 一篇近期文章详细描述了一个复杂的调试过程,涉及Linux内核中的自旋锁问题,由使用eBPF(扩展伯克利数据包过滤器)的CPU分析器触发。核心问题源于分析器的代码(使用内核辅助函数`bpf_ringbuf_reserve`)与内核上下文切换处理之间的交互导致的死锁。 问题并非直接由有缺陷的eBPF代码引起,而是由于与新引入的自旋锁(在内核5.15中)的交互以及它未能正确处理意外的锁定场景。具体来说,分析器从中断和非中断上下文都合法地使用环形缓冲区,导致争用。 内核尝试使用`rqspinlock`来缓解死锁,但未能完全解决问题,反而可能导致长时间延迟。文章强调了在eBPF环境中编程的挑战,开发者依赖内核提供的辅助函数,并期望验证器确保安全性。最终,已实施修复程序以允许从这些场景中立即恢复,并且存在针对旧内核版本的解决方法。
相关文章

原文

We’ve been working on the Linux version of Superluminal (a CPU profiler) for a while now, and we’ve been in a private alpha with a small group of testers. That was going great, until one of our testers, Aras, ran into periodic full system freezes while capturing with Superluminal.

We always pride ourselves on Superluminal “Just Working”, and this was decidedly not that, so we of course went hunting for what turned out to be one of the toughest bugs we’ve faced in our careers.

The hunt led us deep into the internals of the Linux kernel (again), where we learned more about spinlocks in the kernel than we ever wanted expected to know, and we ended up helping to find & fix a number of issues along the way.

Initial analysis

The problem he was running into was that on his Fedora 42 machine (kernel 6.17.4-200), the system would periodically freeze for short periods while a Superluminal capture was running:

联系我们 contact @ memedata.com