LWN:SLUB分配器的下一步计划!

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

What's next for the SLUB allocator

By Jonathan Corbet
May 20, 2024
LSFMM+BPF
Gemini-1.5-flash translation
https://lwn.net/Articles/974138/

Linux 内核中存在两个级别的基本内存分配器:页分配器 (page allocator),以页为单位分配内存;以及 slab 分配器 (slab allocator),分配任意大小的块,通常(但不一定)小于一个页。slab 分配器是内核中常用函数 kmalloc() 的底层实现。在 2024 年 Linux 存储、文件系统、内存管理和 BPF 峰会 上,slab 维护者 Vlastimil Babka 对 slab 级别最近的变动进行了介绍,并讨论了即将到来的变动。

曾经,内核包含三个 slab 分配器实现。在 6.4 版本中,这个数字降至两个,当时 SLOB 分配器(针对低内存系统)被移除。Babka 在 2023 年峰会 上表示,当时已经决定移除 SLAB(两个通用分配器之一),只保留 SLUB 在内核中。这个移除动作也在 6.8 版本中完成。内核开发者现在拥有更大的自由度来改进 SLUB,而不必担心破坏其他分配器。他认为没有人对这个移除动作感到不满,直到他看到了最近来自嵌入式开源峰会的 报告,其中包含了一些抱怨。即使在那个场合里,主要抱怨似乎是关于移除发生得太快了的——尽管他认为这已经拖延了太久。无论如何,似乎没有人强烈要求将 SLAB 重新加入内核。

b513c8a748db1266beccd8607e872f74.png

去年,一些人表达了 SLUB 比 SLAB 对于某些工作负载更慢的担忧。但现在,没有人致力于解决任何剩余的问题。David Rientjes 说 Google 仍在努力过渡到 SLUB;在这个过程中,他们发现使用 SLUB 解决了一些在使用 SLAB 时观察到的抖动问题,因此 Google 的开发人员对这次变更感到满意。

Babka 说他一直在努力减少控制组中内核内存分配的统计(accounting)所产生的开销;这种成本体现在微基准测试(microbenchmarks)中,并且“Linus 对此很不满”。有一些改进已准备好在 6.10 版本中实现,但还有更多工作要做。slab 开发的另一个领域是 堆喷射防御(heap-spraying defense);这些补丁对他来说有点问题。他可以将它们视为内存管理变更进行审查,但他缺乏对安全方面进行判断所需的专业知识。

目前正在进行有关对象缓存和预填充的工作。这项功能将维护一个 per-CPU 的对象数组,用户可以选择是否打开这个功能;他们将能够在分配之前对对象进行预填充(或者预分配),以便它们在需要时随时可用。例如这对于在临界区中分配的对象非常有用。最初的目标用户是 maple tree 数据结构,它目前在进入临界区之前批量分配最坏情况下的对象数量,然后在之后返回未使用的对象。对象缓存将消除这种来回操作,同时确保在需要时可以分配对象。

Michal Hocko 指出,推动这项功能的真正问题是 GFP_ATOMIC 分配与 __GFP_NOFAIL 标志组合起来的情况;如果内存紧张,内核很难满足这种组合。分配器目前在遇到这种组合时会发出警告;他表示,开发者应尽量避免使用这种组合。预填充的对象缓存是解决这个问题的一种方法。将来,可能会为这种情况添加某种预留机制。

maple tree 暴露的另一个问题与其使用 kfree_rcu() 释放对象的做法有关——这在内核代码中经常使用。问题在于,以这种方式释放的内存不会立即供其他用途使用;它必须首先等待 RCU 优雅期过去。这会导致 kfree_rcu() 使用的 per-CPU 数组溢出,导致刷新(flushing),并且可能导致很快就需要重新填充进来,从而再次启动这个循环。这个问题在 Android 上更加严重,RCU 回调只在某些 CPU 上运行,这对处理未运行回调的 CPU 上的 per-CPU 数组就完全没有作用了。

计划创建一个 kfree_rcu() 变体,将对象放入数组并将其放在一边,以便作为一个整体释放。一旦发生这种情况,整个数组就可以放回池中,并提供给所有 CPU 使用。这个数组将被称为“sheaf”;它将存储在每个节点的“barn”中。一个潜在的问题是,在释放对象时可能需要分配一个新的 sheaf;应尽可能避免在释放路径中进行分配。该小组讨论了替代方案,但没有得出任何结论。

与此同时,Babka 并不满足于只移除 SLOB 和 SLAB;接下来要移除的目标是 BPF 子系统使用的特殊分配器。这个分配器旨在任何调用上下文内都可以使用,包括不可屏蔽中断 (NMI) 场景中。BPF 维护者 Alexei Starovoitov 显然赞成进行这个移除,如果 SLUB 能够处理相同的用例的话。BPF 分配器目前为分配的对象添加了 llist_node 结构,使它们更大;切换到 SLUB 将消除这种开销。这也将使 SLUB 成为 NMI 安全的,并消除维护另一个分配器的必要性。

Babka 还希望集成 objpool 分配器,该分配器在 6.7 内核中添加,没有与内存管理开发者进行任何协商。最后,随着会议时间的结束,Babka 提到了最终集成 mempool 子系统(这是另一种预分配对象的方式)的可能性。SLUB 分配器可以为系统中的所有 mempool 预留对象,从而减少整体开销。不过,这看起来是 2025 年峰会讨论的话题。

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

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

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

04c1768a1b4da99054d7b92d64dd2deb.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值