一个已经开发了一段时间的补丁系列引入了“束”的概念,为 SLUB 内核分配器提供了一个可选的、按 CPU 和基于数组的缓存层。看起来,如果没有人提出反对意见,这些“束”补丁可能会在 Linux 6.18 内核中引入。
SUSE 工程师 Vlastimil Babka 一直负责 SLUB 分配器代码中的“束”工作。他在 LKML 邮件列表上对补丁系列进行了说明:
“这个系列为 SLUB 添加了一个可选的 percpu 数组缓存层。它已经发展到一种状态,其中带有 sheaves 的 kmem 缓存与所有 SLUB 功能(slub_debug、SLUB_TINY、NUMA 本地性考虑)兼容。因此,我的希望是它最终可以启用所有 kmem 缓存并取代 cpu(部分)slabs。
请注意,“sheaf”这个名字是由 Matthew Wilcox 发明的,所以我们不会像原始的 Bonwick 论文那样称数组为“杂志”。因此,sheaves 的每个 NUMA 节点的缓存被称为“谷仓”。
引入“束”和“谷仓”的补丁已经排队在 slab.git 的 slab/for-next 分支中,并且被标记为“slab/for-6.18/sheaves”。

由于“束”补丁位于“-next”分支中,并且标记为 Linux 6.18 周期,它们很可能会在 10 月初的 Linux 6.18 合并窗口中提交。
关于“束”的好处,信件继续解释道:
“动机主要来自与 VMA 锁定可扩展性以及相关的枫树操作的相关工作。这就是为什么在补丁集中启用了 VMA 和枫树节点缓存。在 v5 中,我包括了 Liam 的完整枫树树转换补丁,该补丁使用了改进的预分配 API。
启用了束的缓存有以下预期的优势:
– 更便宜的快速路径。对于分配,由于 local_trylock(),不再需要本地的双 cmpxchg,而是变成了 preempt_disable()和没有原子操作。同样适用于释放,否则对于短期分配,它只是一种本地的双 cmpxchg(因此在释放对象时,同一 CPU 上仍然活跃的同一 slab),否则成本更高的锁定双 cmpxchg。
– kfree_rcu() 批处理和回收。kfree_rcu() 将对象放入单独的 percpu 簇中,只有当簇满时才将整个簇提交给 call_rcu()。在宽限期后,簇可用于分配,这比释放和重新分配单个 slab 对象(即使是 kfree_rcu() 实现本身执行的批处理)更高效。如果只有一些 CPU 允许处理 rcu 回调,簇仍然可以通过共享 barn 供同一节点上的其他 CPU 使用。maple_node 缓存使用 kfree_rcu(),因此可以从中受益。
– 预分配支持。预先填充的簇可以被私有借用以执行不允许中途阻塞的短期操作,并且可能需要分配一些对象。如果已知分配数量的上限(最坏情况),但实际上平均需要的分配数量要少得多,那么借用和归还簇比为最坏情况执行大量分配然后释放大量未使用对象更高效。Maple 树的写操作应该会从中受益。
– 与 slub_debug 的兼容性。当为缓存启用 slub_debug 时,我们简单地不创建 percpu 的束,以便调试钩子(在节点部分列表慢路径上)能够像以前一样被访问。对于 CONFIG_SLUB_TINY 也是如此。束预分配仍然通过重用超出缓存束容量请求的(无效)路径来工作。这与现有的方法一致,即调试绕过快速路径,SLUB_TINY[更倾向于]内存节省而非性能。”
这应该是对 Linux 内核的一个很好的补充,为利用这个新的 per-CPU 缓存层功能而改编的代码。希望它在 Linux 6.18 内核的道路上一切顺利。
转自 Linux Looks Ready To Introduce “Sheaves” For Opt-In Per-CPU Array-Based Caching Layer – Phoronix
Linuxeden开源社区