LWN:NUMA系统上对内核代码段复制多份!

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

Kernel-text replication on NUMA systems

By Jonathan Corbet
January 5, 2024
ChatGPT translation
https://lwn.net/Articles/956900/

内核开发人员通常会想方设法减少内核本身使用的内存;这部分内存对人们实际想在其系统上运行的工作负载来说是无法利用的。这类内存数量越少,也往往意味着整体性能更好。但有时花费一些额外的内存可能会让系统更快。内核代码段(可执行代码)和只读数据在 NUMA 系统中的复制可能就是一个例子;已经有一些补丁在这两个体系结构中添加了这种功能。

非一致性内存访问(NUMA, Non-uniform memory access)系统被分为多个节点,每个节点通常包含一些 CPU 和一些内存。系统中的所有内存都可以从任何 CPU 访问,但在访问本地节点的内存的时候会比访问远程节点的内存快得多。因此,内核会尽力尝试将工作负载及其内存保留在相同的节点上,并提供了一系列丰富的系统调用,允许应用程序控制其内存在系统中的位置。

但是,系统应该如何放置那些所有节点都需要的数据呢?对于可写数据,通常没有太多可以做的。必须只能在某一个位置放置一个单一的副本。最好的情况是,该数据可以分布在所有节点上,以便在任何地方访问的时间相对毕竟平衡。对于只读数据(如内核文本)也可以采用相同的方式,使得工作负载在其位于的任何节点上的情况下性能都相似,尽管(正如我们将看到的)并非所有体系结构都这样做。但该数据的只读性质还暗示了另一种优化方式:在每个节点上制作该数据的副本,以便每个节点都可以快速访问。对于像内核代码本段这样经常访问的数据,应该可以看到性能提升,损失的代价是需要额外的内存来存储副本。

2023 年 5 月,Russell King 在 arm64 架构上发布了内核代码段复制(kernel-text replication)功能的实现。这项工作出现在该架构上的事实,就表明了 CPU 设计已经发生了变化;NUMA 架构过去只限于高端服务器,但现在它们在手机中同样普遍。正如 King 所指出的,arm64 架构目前将内核代码段放在了单个节点上,导致系统中性能不均。将内核文本复制到每个节点将使每个节点都能够本地访问,从而提高性能。

每个节点上的代码段副本自然会位于不同的物理地址。然而,必须把这个差异隐藏起来,因为各个任务会在节点之间迁移,因此它们需要在相同的虚拟地址上来访问内核。King 通过更改内核代码段(以及只读数据)的放置位置,使得它可以被自己的顶层页表目录(top-level page-table directory)覆盖来解决这个问题。顶层页表目录可以轻松地为每个节点设置不同的值,从而生成映射,使得内核代码段无论在哪里访问都是位于相同的虚拟地址的,尽管物理位置会不一样。

在配置好之后,大部分工作就只是分配更多的内存,然后正确地进行映射,并将内核文本复制到其中。当然,还有一些细节。例如,内核代码段并非完全是只读的;在运行时有时(例如启用 tracepoint、加载模块或安装 BPF 程序时)内核会在其自己的代码段上进行动态修改。现在,必须在内核代码段的所有副本上都要重复进行这些操作。King 在他的帖子中也指出了一些未解决的问题。内核代码段复制与内核地址空间布局随机化(KASLR)不兼容,因此必须禁用该安全机制。代码段复制还破坏了 KASAN;King 请求帮助修复,但似乎并没有得到帮助。

在回复这个帖子时,Ard Biesheuvel 表示“这里提出的方法是合理的,但有很大的入侵性”。他指出,如果和他的补丁(添加对 LPA2 的支持,即 arm64 的大物理地址)合并,将会再出现一个跟代码段复制不兼容的问题。他建议使用另一种方法,也就是“受保护的 KVM(pKVM)”,在每个节点上运行一个单独的内核,使用该内核的页表来映射复制的内核代码段。King 对这个想法作出了积极的回应,但是在他在七月份发布了复制补丁的第二个修订版时,保持了与第一个版本相同的方法。

这个帖子几乎没有得到评论,这项工作似乎已经停滞不前。这是不幸的,因为正如在原始帖子中指出的那样,它可能带来实际的好处:

“毫无疑问,内核代码段复制的性能改善取决于工作负载,似乎在类似数据库的工作负载中就已经获得了 6%到 17%的增益。当与 NUMA 感知的用户空间相结合时,这可以引出超过 50%的改善。”

自七月份以来,King 的补丁没有再次发布。然而,这个复制想法依然存在,如 Artem Kuzin 发布的 这个patch系列中所示,它是为 x86 平台添加了复制支持。封面信表示他参考了 King 的工作,并表达了希望能够一起推动这两个改动的愿望。这个相对较大的补丁集不是直接基于之前的工作的。

arm64 体系结构清晰地分离了内核和用户空间的页表,使得复制变得更容易实现;相反,x86 没有这种分离,因此实现起来更为复杂。该系列不仅限制了节点特有的页表目录到顶层,而且还必须创建节点特有的 PUD 和 PMD(四级系统中的下两级)目录。然而,这种方法能够支持 KASLR 和 KASAN(尽管显然 KASAN 尚不能与五级页表一起工作)。

这个系列的评估结果似乎表明存在显著的性能提升。

这个系列比 arm64 补丁受到的关注更少。可能原因之一是这项工作没有详细的文档,但它也是在 12 月 28 日发布的,这意味着大多数开发人员还没有机会好好看一看。一旦开发社区从假期完全恢复过来,关于这项工作的讨论可能会加强。

从理论上讲这个想法不应该有什么争议。在复制内核所需的额外内存量不大、尤其是在具有更大内存的 NUMA 系统的环境下这个内存空间增长不是什么问题,而性能收益看起来很显著。然而,这个改动在任何体系结构上都需要对内核核心代码进行相当多的侵入性修补,并且还可能增加后续其他重要功能实现时的复杂度。这项工作是否能进入主线代码库,最终将取决于人们是否认为这种改动增加的复杂性相对所带来的好处来说也是值得的。

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

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

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

format,png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值