Hotdry.
systems

Linux 内核 swap table 现代化:XArray 元数据重构的性能突破

深入分析 Linux 内核 swap table 如何通过 XArray 元数据重构实现 5-30% 的性能提升,涵盖设计原理、并发优化与工程落地参数。

背景:swap 子系统的数据结构演进

Linux 内核的 swap 子系统长期扮演着 “沉默的守护者” 角色,在物理内存不足时,将不活跃的页面换出到磁盘或 ZRAM 压缩内存中。其性能直接影响系统在内存压力下的响应能力。swap 缓存(swap cache)作为核心元数据管理层,历史上经历了两次重要的数据结构变革。

最初,内核使用基数树(radix tree)来管理 swap 条目到页面的映射。基数树适合稀疏数据,但需要开发者手动处理锁机制,代码复杂且易出错。随着 Linux 4.20 到 5.x 系列的演进,XArray 作为基数树的现代化替代品被引入。XArray 提供了内置的锁机制、RCU(Read-Copy-Update)安全性以及更简洁的 API,逐步在页缓存(page cache)等场景中取代基数树。swap 缓存也随之迁移到 XArray 作为其后端存储。

然而,XArray 本质上仍是一种树形结构。对于 swap 操作而言,许多场景(如批量换入换出)事先已知目标集群(cluster),树形遍历的开销成为不必要的瓶颈。2025 年 Linux 存储、文件系统、内存管理与 BPF 峰会上,开发者 Kairui Song 提出了用 swap table 重构 swap 缓存的计划。该工作的第一阶段于 Linux 6.18 合并,标志着 swap 子系统现代化进入新篇章。

设计剖析:从树到数组的范式转变

swap table 的核心思想是用一个平坦的、每集群(per-cluster)的指针数组替换 XArray 树。每个数组元素的大小与 64 位系统上的页表项(PTE)对齐,通常为 8 字节,存储一个原子指针。该指针可以指向三种状态:NULL(未使用)、folio(表示正在换入或换出的透明大页)或 shadow(存储被换出工作集的信息)。

这种数组化设计带来了多重优势:

  1. 查找复杂度降低:对于已知偏移量的 swap 条目,访问复杂度从树形结构的 O (log n) 降至数组的 O (1),显著减少了 CPU 缓存未命中和指令开销。
  2. 内存局部性优化:swap 操作常以集群为单位进行,数组的连续内存布局完美契合了 CPU 的预取机制,提升了缓存命中率。
  3. 代码简化:移除了复杂的树操作逻辑,使 swap 核心代码更易于维护和调试。

在并发控制上,swap table 采用了精细化的锁策略。任何对数组元素的修改都必须持有该集群的专用锁,确保了写操作的序列化。而读操作则充分利用了 RCU 机制结合原子读:查找时在 RCU 读侧临界区内进行原子指针读取,若发现有效的 folio,则需在返回前额外获取该 folio 的锁。这种 “集群锁 + RCU” 的混合模型,在保证数据一致性的同时,极大提升了读密集型负载的并发能力。

性能实测:量化提升与开销分析

根据公开的测试数据和补丁讨论,swap table 在多种现实负载中带来了显著的性能提升:

  • 微基准测试:在 usemem 等压力测试中,观察到系统时间(system time)减少高达 28%,swap 吞吐量提升 30%。这直接归因于查找路径的缩短和锁争用的减少。
  • 开发工作流:在内核编译(使用 ZRAM 作为 swap 设备)场景下,整体构建时间缩短了 5-10%。对于长时间、高内存占用的编译任务,此优化能显著提升开发者效率。
  • 数据库负载:在 Redis 运行内存压力测试并执行 BGSAVE 时,请求处理率(RPS)获得了 6-7% 的提升。这表明 swap table 对需要频繁换入换出的服务器应用同样有益。

内存开销方面,初始实现可能因元数据结构对齐而导致每集群开销略微增加。但长期来看,swap table 为后续优化奠定了基础。例如,未来可以合并原有的 swap_map 数据结构,进一步减少元数据的内存占用,实现净收益。

工程落地:监控、调参与演进方向

对于系统工程师和内核开发者,理解如何监控和调优 swap table 至关重要。以下是一些可操作的要点:

关键监控指标

  1. si(swap in)与 so(swap out)速率:通过 vmstat 1 观察,swap table 优化后,在相同内存压力下,这两项数值应能维持更高吞吐或更低延迟。
  2. 系统时间占比:使用 pidstatperf 工具监控内核态 CPU 消耗,特别是在 swap 活跃时,系统时间占比应有下降趋势。
  3. 锁争用统计:可通过 perf lock 或内核的 lock_stat 机制观察集群锁的争用情况,确认并发度是否提升。

配置与调优提示

  • 当前 swap table 作为内核内置功能,无需额外配置,从 Linux 6.18 开始自动生效。
  • 对于自定义内核构建,确保 CONFIG_SWAPCONFIG_SWAP_TABLE 已启用。
  • 性能收益与工作负载的 “集群局部性” 强相关。对于顺序访问 swap 区域的任务(如大数据处理),收益最大;对于极端随机访问,收益可能受限。

未来演进: swap table 的第一阶段主要替换了 swap 缓存查找路径。根据设计规划,后续阶段将进一步整合 swap 子系统的其他元数据,并可能引入动态数组大小调整以适应不同规模的 swap 设备。社区也正在探索将其设计思想应用于其他内核子系统的可能性。

结语

Linux 内核 swap table 的引入,是内存管理子系统持续现代化进程中的一个典范。它通过将元数据结构从通用的树形 XArray 替换为专用的平坦数组,精准地解决了 swap 操作的关键瓶颈。实测中 5-30% 的性能提升,证明了 “专用化” 和 “数据结构优化” 在内核开发中的巨大价值。对于运行高内存压力负载的服务器、开发工作站和嵌入式设备,此次优化将直接转化为更流畅的用户体验和更高的资源利用率。随着后续阶段的开发,swap 子系统有望变得更简洁、更高效,继续稳固地支撑起 Linux 帝国的内存基石。

资料来源

  1. LWN.net, "mm, swap: introduce swap table as swap cache (phase I)", 2025.
  2. The Linux Kernel documentation, "Swap Table", https://docs.kernel.org/mm/swap-table.html.
查看归档