关注了就能看到更多这么棒的文章哦~
Optimizing single-owner memory
By Jonathan Corbet
May 26, 2023
LSFMM+BPF
DeepL assisted translation
https://lwn.net/Articles/932391/
内核里的内存管理子系统的主要优化目标是要能最大程度地共享资源。但是,正如 Pasha Tatashin 在 2023 年 Linux 存储、文件系统、内存管理和 BPF 峰会的内存管理会议上所指出的,很多内存都只有一个 owner,永远不会被共享。他向抱有怀疑的人们介绍了一些优化内存管理的想法。
Tatashin 一开始介绍说,他试图解决的问题是谷歌所特有的,但他认为其他人也可能遇到这种情况。他所说的内存就是从来不共享的匿名内存(anonymous memory)。一个进程可能分配了大量的内存,然后从来不进行 fork 调用,或者它可能使用了 madvise()来告诉内核不要与任何子进程共享一定范围的内存。在谷歌,90%的内存都是不共享的,因为谷歌非常倾向于使用线程而不是独立的进程。
他说,对于这种工作场景来说,内核的内存管理并没有很高效。系统物理内存的大约 1.6%被用于 page structure,用来管理这些内存。谷歌的服务器群里包含了 PB 级别的内存,这也是它最昂贵的组成部分,所以这 1.6%的开销是相当重要的。他说,page structure 的存在是为了管理所有各种类型的内存,对于单用户匿名内存来说它并不是必需的。
消除内存共享的可能性,可以带来一些好处。之前他总是不得不调试一些内存被错误地共享的问题,这往往是由于驱动程序的错误造成的。没有共享的话这些错误就不会出现了。由于单一 owner 的内存总是可迁移的(migratable),因此总是可以拼成 1GB 的 huge page,这也有助于性能。
Tatashin 描述了一个有两个组成部分的单一 owner 内存驱动程序。用内存池管理 1GB 的内存块(chunk),这些内存块可以来自多个来源,包括 hugetlbfs、设备 DAX 或 CXL 内存池;这些内存都不需要跟 page struct 关联起来。内存池将努力把可移动的内存分配和不能移动的内存分配区分开。另一块是驱动程序本身,它用较小的 chunk 来管理这部分内存,并使其可供进程使用。它实现了一种新型的虚拟内存区域(VMA),被标记为 page-frame-number(PFN)映射的,这样内核不会想要为它找到对应的 page structure。这个驱动可以支持大多数面向内存的调用,如 madvise()。
然后,用户空间进程可以打开/dev/som 来分配 single-owner 的内存供其使用。不过,Tatashin 在实现上遇到了一些问题,包括 PFN 映射的 VMA 在内核中并不是所有地方都支持的。尤其是,get_user_pages()系列函数无法配合它们,这使得在许多情况下无法使用 single-owner 内存。
他说,页面老化(page aging)也变得更加难管理了,因为在没有 page structure 的情况下就没有 LRU list 信息了。一个解决方案是针对此目的创建一个新的、更小的 page structure 类似结构;到目前为止,他一直在抵制这个方向,但没有更好的解决方案。这种内存不支持 swap,也不支持 NUMA 布局或 hardware poisoning 等。
Tatashin 说,他意识到实现 folio 以及 page descriptor 的工作最终将面临和解决许多类似的问题。但是,他说,那部分工作预计仍然需要几年的时间才能完成,他希望能更快地得到一个解决方案。Matthew Wilcox 插话说,如果 Tatashin 帮忙的话,folio 的工作会更快完成,并说 single-owner 内存的工作正试图消除内存管理子系统,但最终会变成对它进行重新实现。他说,这项工作最终可能会像 hugetlbfs 一样,包含了许多重复的内存管理功能。他很怀疑最终会有真正的收获。
随着会议的结束,小组中的其他人也表达了类似的感受。对这个特殊用途的分配器来说,会面临无穷无尽的功能添加,所以它将一直在增长。John Hubbard 表达了会议室里的共识,他建议 Tatashin 还是要努力来让内存管理核心代码更适配他的需要。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~