作为 Linux 内核的缔造者,Linus Torvalds 的技术水平一直备受赞誉。近期,他再次用实际行动证明了自己的能力:仅通过 21 行代码的优化,就让 Linux 内核的多线程性能提升了 2.6%。
意料之中,这在开源社区中引发了广泛关注,许多开发者感慨:“大佬不愧是大佬,轻易不出手,一出手就惊艳全场。”
Meltdown 和 Spectre 漏洞及其影响
据了解,本次改动的核心代码提交名为 x86/uaccess:避免在 64 位 copy_from_user() 中使用 barrier_nospec()。顾名思义,Torvalds 这次的优化调整主要就是移除 copy_from_user() 函数中的 barrier_nospec()。
在进一步讨论 Torvalds 的优化之前,我们可能需要先了解一下 barrier_nospec() 的由来——它涉及到 2018 年公开的两大 CPU 漏洞 :Meltdown 和 Spectre。
2018 年,Meltdown 和 Spectre 漏洞给全球硬件和操作系统厂商带来了巨大的安全威胁,这些漏洞主要利用了现代 CPU 中的“预测执行”机制,即通过预判即将执行的代码提前载入指令和数据,从而节省实际执行时的等待时间。本质上来说,这一特性可极大提高系统的运行效率,但其缺陷在于:如果 CPU 预测错误,那么其存储在缓存中的数据就有可能被攻击者获取。基于此,Meltdown 漏洞主要影响 Intel 的 CPU,而 Spectre 漏洞则对包括 Intel、AMD、ARM 在内的多种架构均有影响。
为了缓解这些漏洞,自 2018 年以来,Linux 内核就引入了 barrier_nospec() 等方法,可用于阻止特定情况下的预测执行,从而保障系统的安全性。然而,这类补丁的引入也导致了显著的性能下降,特别是在频繁使用系统调用或多线程切换的场景下。
例如,Netflix 高级性能架构师 Brendan Gregg 就曾对 Meltdown 漏洞的 Linux 补丁 KPTI 进行测试,并明确指出该补丁确实会导致 CPU 性能显著下降:在某些极端情况下,KPTI 补丁的性能开销甚至超过 800%,而高调用频率的代理服务器和数据库等应用尤为受到影响。
Torvalds 的优化改动及其影响
而 Torvalds 一直是性能优先的坚定支持者。他认为,安全性补丁固然非常重要,但不应以牺牲过多性能为代价。
基于此,在本次的优化调整中 Torvalds 移除了 copy_from_user() 函数中的 barrier_nospec(),而替代方法是使用指针掩码技术对地址进行处理:Linus 解释道:“64 位 copy_from_user () 中的 barrier_nospec () 函数运行速度很慢。如果地址无效,可以使用 pointer masking 来强制用户指针全为 1。”
简而言之,当检测到用户态传入无效地址时,该优化会将地址全部设置为“1”,这样就避免了无效地址引发的不必要操作。以下为 Torvalds 对代码的具体改动,可以看到整体只涉及 21 行代码:
据 Linux 内核的测试机器人反馈,在多线程环境下,Torvalds 这一改动在 per_thread_ops 基准测试中实现了 2.6% 的性能提升——虽然表面上看只是微小的 2.6%,但考虑到 Linux 运行在全球数百万台服务器、云服务和本地设备上,这一性能增幅将在全球范围内带来巨大效益。
Torvalds 对 x86 架构的深厚理解也是促成此次优化的关键原因之一。正因为他在处理器架构方面的技术专长,才得以在保障安全的前提下,最大限度地优化性能。这也令许多人联想到了在 Linux 基金会成立之前,Torvalds 曾收到过芯片厂商 Transmeta 的聘请:要求他为 Crusoe VLIW 芯片的构建提供底层专业知识,最终这款芯片可通过仿真来运行 x86-32 代码。
据悉,本次 Torvalds 的改动将作为性能优化的一部分发布在即将到来的 Linux 6.12 稳定版中。在 Linux 6.12 的整个开发过程中,Torvalds 已逐步通过多个 rc 版本测试和发布了各类改进功能和稳定性增强,包括其他多项修复和改进,例如对 Bcachefs 文件系统和各种 bug 的修复。
从目前来看,如果一切顺利的话, Linux 6.12 稳定版将于 11 月 17 日发布。
参考链接:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0fc810ae3ae110f9e2fcccce80fc8c8d62f97907
https://www.theregister.com/2024/11/06/torvalds_patch_linux_performance/