2026-06-06 内核社区日报
khugepaged 折叠 mTHP 功能获 Andrew Morton 合并确认入 mm-unstable、smaps_rollup 改用 per-VMA lock 降低 lmkd 高频读取延迟、alloc_tag 新增 ioctl 过滤接口提升 /proc/allocinfo 查询效率——内存子系统性能与可观测性同步推进。
🧠 重点 · 内存
1. khugepaged 添加 mTHP 折叠支持(v19 获确认,已入 mm-unstable)
发生了什么: Nico Pache 的 khugepaged 折叠匿名内存到 mTHP 系列第 19 版获得 Andrew Morton 的确认,并被更新到 mm-unstable 分支。该版本的改动包括:用线性前向扫描算法(linear forward-walking approach using offset + order)替代原有的 DFS 栈算法;移除 mthp_range 结构及相关栈操作;重命名 mthp_bitmap 为 mthp_present_ptes;修复结果传播,使 mthp_collapse() 返回 enum scan_result 并正确传递 SCAN_ALLOC_HUGE_PAGE_FAIL 和 SCAN_PTE_MAPPED_HUGEPAGE;修正 v18 中的潜在 use-after-free 问题;并调整允许在较低 order 重试的失败集合。整体代码的净变更量为 +100 / -122 行。
为什么重要: 该系列 v19 已被 Andrew Morton 更新到 mm-unstable 分支。
2. vmpressure:在 cgroup v2 上跳过 tree=true 开销,节省 CPU / 内存 / 代码
发生了什么: Usama Arif 提交系列(2 patches)裁剪 vmpressure 在 cgroup v2 上的无效路径。mm/vmpressure.c 中的 vmpressure() 函数有两个输出:@tree=false 用于 in-kernel socket 压力(TCP/SCTP),仅服务于 cgroup v2;@tree=true 用于 cgroup v1 用户态 eventfd 通知(v2 无此接口)。该系列:
(1)扩展早期返回,直接跳过 cgroup v2 + tree=true 分支(该分支的 events 列表在 v2 上始终为空,但仍会执行锁/累加/schedule_work/parent-walk 等完整路径)。bpftrace 在一台 176 核 v2 生产主机上测得每分钟约 16,200 次此类无效调用。
(2)将 cgroup v1 用户态 eventfd 接口(struct vmpressure_event、events 列表及其 mutex、work_struct 及其 handler、parent walk 及注册/注销函数等)拆入新文件 mm/vmpressure-v1.c,仅在 CONFIG_MEMCG_V1=y 时编译。mm/vmpressure.c 保留共享部分及 tree=false 的 socket 压力路径,代码量减半。struct vmpressure 中 v1-only 字段通过 #ifdef CONFIG_MEMCG_V1 包裹。内存节省:struct vmpressure 从 112B 减至 24B,struct mem_cgroup 从 1664B 减至 1536B。
为什么重要: 对 cgroup v2-only 主机(当今绝大多数生产环境),该系列消除了 reclaim 路径中一个因全局锁 sr_lock 引起的竞争点,同时减小了 struct vmpressure 和 struct mem_cgroup 的内存占用量,并清理了代码边界。
3. alloc_tag:为 /proc/allocinfo 添加 ioctl 过滤接口(v3)
发生了什么: Abhishek Bapat 与 Suren Baghdasaryan 合作,将原本纯文本的 /proc/allocinfo 扩展为支持 ioctl 的二进制查询。v3 系列(6 patches)添加:
ALLOCINFO_IOC_CONTENT_ID:获取内容标识符,用于检测文件是否变更。- 基于 tag 的模块名、函数名、文件名和行号的过滤。
- 基于分配总字节大小范围
[min_size, max_size]的过滤。 - 基于 accuracy 标志(
CODETAG_FLAG_INACCURATE)的过滤。
配套 kselftest 覆盖了 filename、function、size、lineno 几种过滤场景。
为什么重要: /proc/allocinfo 是内核内存分配 profiling 的主要用户接口,但纯文本解析在大量分配场景下(现代服务器启动期间可达百万条)效率极低。ioctl 接口允许用户空间通过一次系统调用精准筛选感兴趣的子集(如特定驱动或模块的分配),避免浪费 CPU 和内存资源。该设计参考了 procfs 的标准 ioctl 范式。
4. memcontrol stock:将批量 charging 缓存从 mem_cgroup 下移至 page_counter 层级(v3)
发生了什么: Joshua Hahn 提交了该系列的 v3,包含 6 个补丁:[1/6] 引入 per-page_counter stock;[2/6] 在 page_counter_try_charge 中使用 page_counter_stock;[3/6] 引入 stock drain API;[4/6] 将 memcg 转换为使用 page_counter_stock;[5/6] 优化 cgroup v1 的 memsw stock;[6/6] 移除未使用的 memcg_stock 代码。
为什么重要: 该系列将 per-CPU 批量 charging 缓存(stock)从 mem_cgroup 层迁移至 page_counter 层,使层级化 cgroup 树中每个计数器(memory.current、memsw 等)均能独立缓冲批量 charge/uncharge,减少向上传播时各祖先 page_counter 上的原子操作频率。在容器密度高的生产环境(Kubernetes 等 cgroup v2 深层树)中,此类热 atomic 计数器的 cache-line 竞争是 reclaim 路径的真实瓶颈之一。同时将 cgroup v1 的 memsw stock 单独优化,并清理已无用的 memcg_stock 代码,使内存计费路径更简洁。
来源
5. 停止对 hugetlb 映射在 get_unmapped_area 中的特殊处理
发生了什么: Oscar Salvador 提交 8-patch 系列,清理各架构中 get_unmapped_area 对 hugetlb 映射的特殊处理。历史原因:hugetlb 映射需要额外对齐(huge page size),早期各架构在 arch_get_unmapped_area* 中通过 info.align_mask 为 hugetlb 预留空间。但实际上 hugetlb_get_unmapped_area() 已自行处理了这部分对齐。该系列:
(1)在 hugetlb_get_unmapped_area() 中编码额外对齐 padding。
(2)移除了 x86、s390、loongarch、sparc64 的 arch_get_unmapped_area* 中的 hugetlb 特殊判断。
(3)sparc32 没有 hugetlb,直接删除相关代码。
(4)移除不再使用的 huge_page_mask_align 宏。
为什么重要: 消除了一个已知的回归源头(AMD 15h Family 上 align_va_addr 下 hugetlb 映射可能出错)。更重要的是,让 mmap 路径的代码更干净,不再将 hugetlb 作为特例处理,降低后续新增架构或调整 get_unmapped_area 时的维护负担。
6. smaps_rollup 改用 per-VMA lock,消除 lmkd 高频读取与 mmap 的锁竞争
发生了什么: Suren Baghdasaryan 提交 2-patch 系列,将 /proc/pid/smaps_rollup 的读取锁从 mmap_lock(全进程范围读锁)切换为 per-VMA lock。Patch 1/2 将 lock_vma_range() 返回值从 bool 改为 int,以正确传播底层 lock_ctx_mm() 的错误码;Patch 2/2 在读取 smaps_rollup 时逐 VMA 加 per-VMA 读锁迭代,不再持有全局 mmap_lock。
为什么重要: Android 的低内存终止守护进程(lmkd)以极高频率读取每个进程的 /proc/pid/smaps_rollup 来估算进程实际 RSS。原有实现在整次读取期间持有目标进程的 mmap_lock 读锁,与进程自身的 mmap/munmap(需写锁)互斥——高频扫描时,lmkd 会持续阻塞被监控进程的 VMA 修改,产生可见延迟。切换为 per-VMA lock 后,smaps_rollup 的逐 VMA 读取与进程的 VMA 修改可并发进行,消除了 lmkd 与被监控应用之间的锁竞争,降低 Android 内存压力下的应用响应抖动。
🔧 其它子系统
eBPF / bpf-next
- tracing_multi link v8:Jiri Olsa 发布 v8 系列,引入
BPF_TRACE_FENTRY_MULTI/BPF_TRACE_FEXIT_MULTI等 attach 类型,允许一个 BPF 程序同时 attach 到多个内核函数(通过 BTF ID 数组或函数名 pattern)。包括 session 支持、cookie 支持、libbpf API、完整的 selftests 和 benchmark。这是一个重量级特性,将 BPF tracing 的灵活性大幅提升。[来源](https://lore.kernel.org/bpf/20260606123955.345967-1-jolsa@kernel.org/) - PTR_TO_FLOW_KEYS 越界修复:Nuoqi Gui 修复了 verifier 中
check_flow_keys_access()只检查insn->off而未折叠reg->var_off.value的 bug,使常量偏移导致的数组越界可以被正确拦截。[来源](https://lore.kernel.org/bpf/20260606-c3-01-v3-v3-0-97c51f592f15@mails.tsinghua.edu.cn/) - bpf_set_retval 参数校验合入:Xu Kuohai 的系列为
bpf_set_retvalhelper 添加参数校验,已被 Alexei Starovoitov 合入 bpf-next。[来源](https://lore.kernel.org/bpf/178070041689.3950549.14630927515894773480.git-patchwork-notify@kernel.org/) - htab_free 中的 sleep-in-atomic 修复:Luo Gengkun 将
htab_map_free_internal_structs的释放操作推迟到 workqueue 中执行,以避免该函数在 RCU_SOFTIRQ 上下文中调用cond_resched()时触发的 “sleeping function called from invalid context” BUG。来源 - cgroup storage cookie 检查收紧:Lin Ma 在修复 CVE-2025-38502 的基础上,进一步检查 cgroup storage cookie 的匹配范围,防止通过 prog array 绕过 cookie 验证。
[来源](https://lore.kernel.org/bpf/86dac3e9-3af2-4bc6-93e5-d62aa70fb362@iogearbox.net/)
文件系统 / VFS
- vmsplice 修复继续:Askar Safin 发出 vmsplice patch 集的修复,解决之前版本的一些问题:将参数类型改回 int、处理 write after partial data 的等待语义(兼容 LTP vmsplice01)、以及重构
wait_for_space至fs/pipe.c供后续复用。[来源](https://lore.kernel.org/linux-mm/20260606061031.3744880-1-safinaskar@gmail.com/)
虚拟化 / Live Update
- PCI Live Update 设备追踪:David Matlack 的系列继续讨论,补丁添加
pci_liveupdate_setup_device()以在设备枚举时获取序列化状态,用于 kexec 后识别并追踪保留的 PCI 设备;同时将CONFIG_PCI_LIVEUPDATE依赖改为64BIT以保证 xarray 键长度。Pranjal Shrivastava 在审阅中对kho_restore_free的使用政策提出讨论。[来源](https://lore.kernel.org/linux-mm/aiPxVxu2sUVQfG9D@google.com/) - Guest memfd 保存:Tarun Sahu 提交 v1 系列,为 Live Update 添加 guest_memfd 的保存/恢复支持。
[来源](https://lore.kernel.org/r/cover.1780667929.git.tarunsahu@google.com)
内存热插拔 / NUMA
- DAX/kmem 原子热插拔:Gregory Price 发布 v4,为
drivers/dax/kmem添加 sysfs 接口,支持将持久内存(NVDIMM/CXL)以原子方式热插拔为普通 DRAM NUMA 节点。来源
👀 值得追的讨论 / Patch
- DAMON Hugepage collapsing RFC v3 收到反馈:SeongJae Park 回复 Asier 的 RFC v3,认为系列方向正确且“getting closer to land”;对各补丁给出具体意见(补丁 1 几乎无问题,补丁 2 似乎不必要,补丁 3 需简化并遵循示例模块模式,补丁 4 对示例模块过于详尽)。来源
⚡ 一句话速览
- mm/memory_hotplug: 修复 HWPoison 大页迁移:Alexandra Diupina 为 6.1 stable 修复了
do_migrate_range()中处理 poisoned large folio 时的逻辑错误。来源 - mm/page_frag 测试:拒绝无效 CPU:Samuel Moelius 的测试补丁,增加对无效 CPU 编号的校验。来源
- DAMON 文档:添加 TLB flush 策略说明:Kunwu Chan 提交补丁,为 DAMON 新增一份关于为何在清除 PTE Accessed 位后避免 TLB flush 的设计决策文档。维护者 SeongJae Park 认为文档内容过于详尽,建议将其核心信息精简后放入现有的
design.rst,或发布到 DAMON 项目博客。来源 - khugepaged collapse 讨论中遇到 process 问题:David Hildenbrand 和 SeongJae Park 就 khugepaged mTHP collapse 系列的评审流程交换了意见,无技术分歧。来源
- docs: memfd_preservation 渲染修复:Pratyush Yadav 修复了 memfd_preservation 文档中的 ABI 渲染问题。来源
- bpf script 签名暴露检测合入:KP Singh 的系列将 BPF 程序签名验证结果暴露到
bpf_prog_aux,被 Alexei 合入 bpf-next。来源 - bpf: defer freeing htab internal structs 补丁收到 AI 审查:Luo Gengkun 提交的补丁将 htab 内部结构释放推迟到 workqueue,以解决 sleep-in-atomic。AI 审查指出多项问题:Fixes 标签错误(应只引用 4f375ade6aa9)、container_of 偏移计算可能错误(
work字段属于bpf_htab而非bpf_map),以及schedule_work返回 false 时可能造成引用计数泄漏。审查建议修复这些缺陷。来源 - bpf: libarena 添加 rbtree 和 spmc queue 数据结构:为 libarena 添加红黑树和 spmc 队列两种数据结构,并引入并行测试框架,该系列已合入 bpf-next。来源