2026-06-03 内核社区日报

mincore 从页表直查 swap entry,性能提升约 10%;memory_failure 框架补齐 shmem 和 KVM guest_memfd 的 MF_DELAYED 支持;secretmem 直接映射首次具备恢复大页能力。

🧠 重点 · 内存

1. mincore:引入 mincore_swap 辅助函数,从页表直查 swap entry,性能提升约 10%

发生了什么: Kairui Song 的系列在 mincore 系统调用中引入 mincore_swap() 辅助函数,将 swap entry 的检查逻辑从原有的页缓存路径中拆分出来。mincore_page() 现在不再处理 swap cache 空间,因此条件判断简化;同时 mincore_swap() 能正确处理 migration、HWPoison 以及 shmem swapin-error 等非普通 swap entry,并且在 !CONFIG_SWAP 时通过 WARN_ON 捕获异常。新代码直接通过 PTE 中的 swp_entry_t 决定 present=0present=1,而不必再走到 swap cache 查找 folio。测试数据:swaped out 的 16G 匿名 mmap 范围,耗时从 488220 us 降到 446763 us;16G shmem mmap 范围从 530272 us 降到 460496 us,约提速 10%。

Usama Arif 在此基础上又提交了补丁,将 mincore_swap() 中非 swap entry(migration/hwpoison/shmem swapin-error)的处理提前到 !CONFIG_SWAP 守卫之前,确保在无 swap 内核上仍能正确判断这些 entry 的存在性。

为什么重要: mincore 是很多内存监控、JIT 运行时和数据库使用的高频系统调用。10% 的加速意味着在交换密集型场景中可减少用户态查询延迟。同时,更严格的输入校验(WARN_ON + 非 swap entry 单独处理)提高了健壮性。

来源
来源(原始 commit 1f2052755c15)

2. memory_failure:重新定义 MF_DELAYED,全面覆盖 shmem 和 KVM guest_memfd

发生了什么: Lisa Wang 发布了 v4 系列(共 7 个 patch),对 memory_failure 的 MF_DELAYED 语义进行澄清和扩展:
(1)明确 MF_DELAYED 表示硬件错误页已被延迟处理(页面被截断或标记为 HWPoison,但实际未立即回收),定义写入 include/linux/mm.h 注释。
(2)truncate_error_folio() 现在可以正确返回 MF_DELAYED,而非之前的 MF_RECOVERED
(3)shmem 的 page cache 处理中添加 MF_DELAYED 分支,当 shmem 页被截断时返回延迟状态。
(4)extra_pins 检查逻辑从硬编码的几个场景推广为:所有 MF_DELAYED 返回后都不应再检查额外 pin,因为页面已从 page cache 移除。
(5)添加 shmem 内存错误测试(selftests)和 KVM guest_memfd 测试,验证 guest_memfd 中发生内存错误后的行为,以及 stage-2 页表清理的正确性。

为什么重要: 之前 memory_failure 对 shmem 页的处理不完整,shmem 页被截断后可能被误判为 MF_RECOVERED 从而跳过 pin 检查,导致后续访问时仍使用错误的物理页。KVM guest_memfd 是机密虚拟机的重要内存后端,支持其 memory_failure 可让宿主机安全处理 guest_memfd 上的硬件错误,避免 guest 崩溃。这组补丁统一了页面延迟处理的接口,为 future 加入更多文件系统后端的错误恢复奠定了基础。

来源

3. secretmem:补丁尝试在页释放后恢复直接映射的大页

发生了什么: secretmem 从 direct map 中移除 base page 时会分裂覆盖的大页映射为 PTE 条目。Lance Yang 的补丁系列添加一个架构 hook,使 secretmem 在将 folio 恢复到 direct map 时尝试让架构恢复大页映射。当前包含 x86 架构的实现。

为什么重要: 反复分裂会使 direct map 中更多区域映射为 PTE,增加同一范围内的 TLB 条目数量,可能加剧 TLB 压力。恢复大页映射可降低此压力。

来源

4. slab:添加 node-track-caller 变体,并隔离 skb 数据区分配到独立 bucket

发生了什么: Pedro Falcato 发起了两个互相独立的 patch:
(1)为 kmem bucket 分配添加一个 node-track-caller 变体。现有的 kmem_buckets_create() 创建的 bucket 在 NUMA 分配时不记录调用者信息,新变体将调用栈记录在 slab 元数据中,便于调试 slab 泄露和跨节点分配。
(2)将网络 socket buffer 的数据区分配(skb->headalloc_skb() 尾部的大块分配)从通用的 kmalloc 桶中隔离出来,通过 __net_buckets 创建一个单独的 bucket。这避免了 skb 数据区污染 kmalloc 桶的内碎片统计,也让 skb 数据的分配/回收路径更明确。

为什么重要: 网络栈是 slab 分配最频繁的使用者之一。隔离 skb 数据区可以准确统计网络分配的压力,防止碎片,同时允许未来为 skb bucket 定制回收策略(比如 bulking)。node-track-caller 变体则是诊断工具,帮助开发者在 NUMA 系统上快速定位来自哪个代码路径的 slab 分配导致远端内存使用。

来源
来源

5. compaction:cap compact_gap() 取上限 COMPACT_CLUSTER_MAX

发生了什么: JP Kobryn 的补丁将 compact_gap() 的返回值上限设为 COMPACT_CLUSTER_MAX(32 页)。原函数返回 2 << order,对 order-9 THP 分配该值为 1024 页,但 compaction free scanner 的隔离工作集受 COMPACT_CLUSTER_MAX 限制(32 页);过大的 gap 导致 kswapd 试图回收过多页面(实际回收仅达到阈值的 18%),并造成 46% 的 order-9 compaction_suitable() 检查因阈值过高而不必要地失败。Vlastimil Babka 在 review 中确认了问题存在,并认可了该改动(Ack)。

为什么重要: 过大的 compact_gap 使 kswapd 在 high-order 失败后持续过度回收,延迟 compaction 介入,降低 THP 分配成功率。capping 后 reclaim 压力显著下降(生产环境数据:pgscan_kswapd 从 ~1.6M 降至 ~449K),同时 compaction 更早开始操作,THP 分配成功率提升(fallback 从 1217 降至 738)。该补丁对齐了 watermark 头寸与 compaction scanner 的实际能力,避免非必要 reclaim 并加速碎片整理。

来源

🔧 其它子系统

  • eBPF / net: Tushar Vyavahare 发布 xsk selftests 简化系列(v2),将 UMEM 属性设置集中到 helper,并移动 UMEM 所有权从 ifobjectxsk_socket_info,使套接字间的 umem 共享更清晰。来源

  • 块设备(Rust): Andreas Hindborg 的 Rust block layer 系列继续收到 Alice Ryhl 的 review 评论,聚焦于 Request private data 的实现细节。来源

  • selftests: clone3_set_tid:Christian Gellermann 修复 clone3_set_tid 测试中 getline()line 指针未初始化问题,将其显式初始化为 NULL,避免在 musl libc 下因 realloc 访问无效指针而触发段错误。来源

  • folio LRU 代码整理: Jianyue Wu 的系列将 mm/swap.c 重命名为 mm/folio_lru.c,并将 page-cluster sysctl 移到 swap_state.c,将 reclaim 内部声明移入 mm/internal.h。减少包含 swap.h 的源码文件,重构而不改功能。来源

👀 值得追的讨论 / Patch

  • filemap_splice_read() 替换讨论: Linus Torvalds 提议完全移除 filemap_splice_read(),改用 copy_splice_read()。Andy Lutomirski 担心这可能会破坏 zerocopy sendfile 等场景。来源

  • ANON_VMA_LAZY(延迟创建 anon_vma): 该系列由 Tao(Honor)提交,Lorenzo Stoakes 等进行 review。讨论焦点包括:VMA 操作分类(fork、remap 等),以及 ANON_VMA_LAZY 标志在 mremap、split、merge 等情况下的行为。Lorenzo 对分类、split 后 rmap、文件映射 COW 等问题提出质疑,作者逐一回应并解释设计方案。来源

  • memory_failure tracepoint 变更破坏 rasdaemon: 内核 commit 31807483d395 修改了 mm/memory-failure.c 中的 tracepoint 格式,导致用户空间 rasdaemon 无法 enable 该事件。问题已报告给相关 maintainer,尚无修复 patch。来源

⚡ 一句话速览

  • Live Update v6 发布: 解除会话与文件数量上限,使用 linked-block 序列化代替固定大小预分配;测试验证 2000 个会话和 500 个文件跨 kexec 成功保留。来源

  • zswap shrink_worker per-memcg cursor 讨论继续: Hao Jia 与 Yosry Ahmed 就 per-memcg cursor 和 proactive writeback 设计进一步交换意见,焦点在于 cursor 在 cgroup 层级变化时的重置策略,以及改用 global lock 替代 cmpxchg 的可行性。来源

  • Enable mTHP for architectures without PMD leaves 补丁讨论: Lance Yang 指出 shmem_init() 等几处代码仍假设 PMD order,询问 SHMEM_HUGE_FORCE 是否应使用可用的 mTHP order。来源

  • slub sheaves 在本地节点分配: Hao Li 提交 patch 使 sheaf 结构分配在所在 NUMA 节点的 barn 中,但 Harry Yoo 指出方案无法解决任务迁移和远端回退导致的混合问题,并提出不归还空 sheaf 到 barn 的替代思路。Hao Li 回应称测试显示性能提升很小,讨论倾向于放弃此方向。来源

  • kmem_cache_alloc_bulk 零大小返回值讨论及 msm 驱动补丁: 邮件线程讨论 kmem_cache_alloc_bulksize == 0 时是否应返回 true(视为成功),以及 msm iommu pagetable 预分配驱动中 p->count 为零时的处理。Rob Clark 提议在驱动函数开头添加 if (!p->count) return 0; 并将 kfree 改为 kvfree。Vlastimil Babka 表示将把此补丁整合到 slab 树的 commit 中,并确认 job 不会被重用,且可将 p->pages 置 NULL 以提高清晰度。来源

针对已退出 leader 线程进程的 pidfd 访问限制,David 提出两种解决方向并征求 Christian 意见。来源

  • DAMON selftests 修复: Kunwu Chan 提交系列补丁修复 DAMON selftests 中的数个 bug,SeongJae Park 将其应用到 damon/next 树。来源

  • mempool_alloc_bulk API 简化: Christoph Hellwig 重写 mempool_alloc_bulk 和 mempool_free_bulk 接口,减少复杂度。来源


日报由 lore.kernel.org / LWN / Phoronix 素材自动生成,技术细节以原文为准。