2026-06-27 内核社区日报
今天内存子系统动作密集:Qi Zheng 提出 Reserved THP 机制,通过预保留连续 PMD 块为关键应用提供确定性大页分配;Johannes Weiner 分析并修复 defrag_mode 下的 reclaim storms;Breno Leitao 为不可恢复的 HWPoison 页增加 panic 选项;seccomp pinned-memfd 参数重定向 v4 继续改进。eBPF 方面,Xu Kuohai 引入 SDK 风格的静态定义追踪探针(BPF SDT)。
🧠 重点 · 内存
1. Reserved THP:为内存预留需求提供确定性 THP 分配
发生了什么: Qi Zheng 提交 RFC 系列 “Introduce Reserved THP”。该系列新增 MIGRATE_RESERVED_THP 迁移类型,通过 thp_reserved_size/thp_reserved_nr 启动参数在 buddy allocator 中预留指定数量的 2M 连续页面,这些页面仅能通过 MADV_RESERVED_THP madvise 策略消耗。系列包含 8 个 patch,分别新增迁移类型、启动预留、分配原语、配额管理(charge/uncharge)、VMA 标志、VMA 合并分裂时配额维护、匿名缺页支持以及 madvise 接口。目标是让 THP 获得类似 HugeTLB 的预留保证,同时保留 THP 的 swap 等内核集成特性。
为什么重要: 当前 HugeTLB 支持预留但不支持 swap,THP 支持 swap 但无法保证分配成功(可能 fallback 到小页)。Reserved THP 结合两者优点,为热升级等需要内存预留的场景提供确定性的大页分配,减少内存浪费(无需像 HugeTLB 预留双倍内存)。同时该系列也是向统一 HugeTLB 与 THP 迈出的探索步骤,未来可在此基础上逐步替代 HugeTLB。
2. 修复 defrag_mode 下的 reclaim storms
发生了什么: Johannes Weiner 提交 v1 系列,包含 4 个补丁:
(1)为 direct compaction 添加 __GFP_FS lockdep 标注。
(2)在 pageblock 请求中支持 non-movable compaction。
(3)将 capture_control 移至页面分配器。
(4)修复 defrag_mode 下的 non-movable reclaim storm。
为什么重要: 该系列修复 defrag_mode 下的 non-movable reclaim storm 问题。
3. HWPoison:为不可恢复页增加 panic 选项
发生了什么: Breno Leitao 发布 v10 系列,包含 6 个补丁:清理保留页的已失效 error_states[] 条目、将不可处理的 kernel 页报告为 -ENOTRECOVERABLE、报告 MF_MSG_KERNEL、为不可恢复页新增 panic 选项、添加 sysctl 文档、以及添加相应的破坏性 selftest。
为什么重要: 该系列为不可恢复的 HWPoison 错误提供了一个 panic_on_unrecoverable_memory_failure 开关,使系统管理员能在无法恢复时选择直接 panic 而非继续执行,从而提供更明确的错误处理策略与可测试性。
4. seccomp pinned-memfd 参数重定向 v4:消除 TOCTOU 窗口
发生了什么: Cong Wang 发布 v4 系列,解决 seccomp user-notification 中 SECCOMP_USER_NOTIF_FLAG_CONTINUE 响应的 TOCTOU 问题。核心改动:
- 新增
SECCOMP_IOCTL_NOTIF_PIN_INSTALL:将 supervisor 持有的 memfd 在目标进程地址空间中建立只读、可密封的MAP_SHARED映射。 - 新增
SECCOMP_IOCTL_NOTIF_SEND_REDIRECT:恢复被陷 syscall 时,将指定参数寄存器替换为上述映射的地址,由内核自己完成 mmap 和安装,避免竞争窗口。 - 新增
__do_mmap()和vm_mmap_seal_remote():支持从当前 mm 向目标 mm 远程安装映射。 - 对重定向后的 syscall 进行外层 filter 的 re-validation。
为什么重要: 当前 seccomp supervisor 在决定放行后,目标进程的参数可能在用户空间被并发修改。本系列从内核层面彻底消除这一窗口,同时保持对 supervisor 透明。v4 相较 v3 的改动包括完善文档、修复 review 中发现的 edge case。该方案对容器安全、沙箱加固有直接影响。
5. mm/vmstat:节点下线时刷新 per-CPU 统计
发生了什么: Gregory Price 提交补丁,在 try_offline_node() 路径中通过 sync_vm_stats() 调度 per-CPU 工作来刷新当前节点的 per-CPU vmstat 增量到全局 pgdat->vm_stat[]。当前实现中,节点下线时 per-CPU 差值残留在各 CPU 上;后续节点重新上线时 pgdat->vm_stat[] 中的对应值永久偏差,导致节点/compact 因 throttle 计算错误而挂起,且 NR_ISOLATED_ANON 递增后永不归零。
为什么重要: 该修复确保节点从在线集合移除前刷新 per-CPU 差值,避免 vmstat 统计永久不一致以及因 throttle 计算错误引发的内存压缩挂起。对于频繁内存热插拔的环境,这一改动保障了 vmstat 的准确性和系统稳定性。
6. BPF SDT 探针 selftests
发生了什么: Xu Kuohai 提交了 BPF SDT 探针的 selftests,包括 read_args(观察者参数检查)、multi_prog(同一 ELF 内多目标程序)、subprog_probe(子程序探针)三个测试用例。测试通过 bpf_link_create 使用 BPF_TRACE_SDT 附加类型,目标程序通过 BPF_SDT_DECLARE 和 BPF_SDT_PROBE 宏声明探针点,观察者程序访问目标探针参数。
为什么重要: 这些测试验证了 BPF SDT 探针的基本机制(探针声明、观察者附加、参数传递)在多场景下的正确性,为后续功能集成提供了保障。
🔧 其它子系统
eBPF
BPF SDT:为 BPF 程序定义编译时静态追踪探针
发生了什么: Xu Kuohai 发布 RFC 系列,引入 BPF 静态定义追踪(SDT)。机制类似 USDT:在 BPF 程序源码中通过 BPF_SDT_PROBE(nargs, ...) 宏嵌入 NOP 指令和元数据,.bpf_sdt_notes 节记录探针偏移和参数寄存器。内核在加载时收集 BTF ID 进行类型校验,当用户附加观察者程序时,将探针处的 NOP 指令 patch 为 CALL 指令,跳转到 trampoline 后执行观察者。观察者可访问探针点的函数参数。与 USDT 不同,BPF SDT 需要显式宏生成函数原型 BTF,使 verifier 能验证探针类型,观察者可类似普通 tracing 程序使用函数原型信息。系列包含 12 个 patch,涵盖 libbpf 解析、内核 map 构建、x86 JIT 支持、selftests。
为什么重要: 该系列扩展了 BPF 内部的可观测性,允许在 BPF 程序自身逻辑中插入编译时类型安全的静态探针,并在运行时通过 patch 激活观察者。verifier 可基于声明的原型校验探针点,观察者程序复用标准 tracing 加载流程。来源
stale runlist element dereference in fallocate:ntfs_attr_fallocate()在ni->runlist.run上持有锁但查询结果可能已被并发操作失效,补丁增加了重新验证。serialize attribute-list replacement with lookups:ntfs_external_attr_find()遍历base_ni->attr_list时使用 raw cursors,与ntfs_attr_set()可能触发的 attr-list 替换并发,补丁引入了序列化保护。
为什么重要: 两个都是经典的 use-after-free 和数据损坏 bug,对 ntfs 用户数据完整性有直接威胁。补丁基于内核社区对 ntfs 的长期维护经验。
Rust
ForLt 拆分与 DevresLt 引入
发生了什么: Danilo Krummrich 发布 v4 系列,将 ForLt trait 拆分为 CovariantForLt(保留协变含义)和新 ForLt(不要求协变性),并添加用于 ForLt 类型的 auxiliary 注册 API registration_data_with(),引入 DevresLt 抽象(用于设备资源的生命周期感知访问),同时更新 PCI 和 IoMem 的 into_devres() 返回 DevresLt。来源
为什么重要: 该系列通过在类型系统中区分协变与非协变生命周期,降低了生命周期抽象误用的风险;同时 DevresLt 使设备资源访问在类型层面附加生命周期约束,提升了 Rust 驱动代码的类型安全性和正确性。来源
👀 值得追的讨论 / Patch
可靠 1GB 页分配的 RFC
发生了什么: David Hildenbrand 在回复该 RFC 系列时给出严厉审查,指出该系列完全不可合并。主要问题包括:遗漏关键维护者 Vlastimil Babka;page_alloc.c 增加约 5000 行;大量由 LLM 生成的不可读注释;__rmqueue_smallest() 从约 20 行膨胀至 604 行;破坏 watermark boost 功能;缺少任何测试。他建议将该系列拆分为多个独立子系列逐步提交,并补充测试、重写代码注释。
为什么重要: 维护者明确否定当前代码质量和设计方向,要求彻底重构。后续该系列必须大幅缩小每次提交的范围、提升可读性并补全测试,否则无法进入主线。
⚡ 一句话速览
- mincore 使用 walk_page_range_vma:Kefeng Wang 的补丁被 Andrew Morton 修改注释,简化了对 VM_PFNMAP 处理的描述(仅说明 “mincore historically reports PFNMAP mappings as non-resident”)。同一邮件中,sashiko 工具报告了四个预存问题,Kefeng Wang 针对
migrate_device.c提出了修复补丁(检查pte_present后再调用flush_cache_page和folio_mark_dirty),David Hildenbrand 认为该检查合理。来源 - device-private PMD 处理修复继续:Wei Yang 对
mm/page_vma_mapped: fix device-private PMD handling提交了简化调整,正在等待 Ack 来源 - vmalloc guard region 加宽以防御 ENTER-based 栈 pivoting:Xiang Mei 提交补丁系列 “mm/vmalloc: widen guard region to defeat ENTER-based stack pivot”,旨在通过扩大 vmalloc guard region 提升内核安全性。来源
- Gladyshev Ilya 发布补丁,通过重构
page_ref_add_unless优化小文件读取和 folio refcount 扩展性;Mike 回复指出内存故障自测失败 来源 - 补丁因引入 bug 被请求撤回:提交者发现该补丁使一个预期的 EOF 失效,因此请求将其 drop 来源
- pagemap 文档修复:Zenghui Yu 修复了 flags location、member name 和 sample code。来源
- memcg 移除废弃宏 clean up:Joshua Hahn 清理 2021 年以来未使用的
for_each_mem_cgroup宏 来源 - memcg/oom 未初始化变量修复:Breno Leitao 补充
memcg1_oom_prepare()stub 中*locked的初始化 来源 - MGLRU memcg reparenting 修复讨论:Shakeel Butt 对
lock_batch_lruvec()函数位置给出偏好,认为其很特定于 memcg 应移至memcontrol.h,但同意在 v3 补丁中暂留vmscan.c,待有第二个调用者时再清理。来源 - docs/mm 括号修正:Manuel Ebner 修复 hmm.rst 和 process_addrs.rst 中的多余/缺失括号 来源
- mm/page_vma_mapped: 使用 huge_ptep_get() 处理 hugetlb PTE:Dev Jain 提交补丁,在
check_pte()中对 hugetlb VMA 使用huge_ptep_get()替代ptep_get(),以避免架构特定的ptep_get()导致pte_pfn()/pte_present()行为错误。Lance Yang 指出该补丁可能向huge_ptep_get()传递未对齐的地址(因 memory-failure 路径中地址可能基于 tail page),Dev Jain 确认并打算在check_pte()内修复。来源 - seccomp pinned-memfd v4 触发 VMA 测试失败:Andrew Morton 回复指出该补丁系列导致 VMA 测试失败。来源
- KVM gmem_invalidate 重命名:Sean Christopherson 将其改名
gmem_free_folio,反映实际语义(folio free 回调而非 invalidate)来源