2026-07-06 内核社区日报
DAMON 迎来两波重大重构:参数验证全部收敛至 core 层、内部 API 与错误处理路径简化,同时新增“数据属性监控”新模式——可绕过访问频率只收集用户自定义探针数据。HWPoison 方面,Jiaqi Yan 的 v6 系列使溶解后的 HugeTLB HWPoison 页真正被 buddy system 拒绝再分配,终结了一个长期的安全缺口。
🧠 重点 · 内存
1. DAMON 参数验证全面统一:所有校验收归 core 层,sysfs/modules 去重
发生了什么:(1)SJ Park 提交了 mm/damon: validate all parameters in the core 系列(v1,8 patches),将分散在 DAMON sysfs 接口、DAMON_RECLAIM、DAMON_LRU_SORT 中的参数有效性检查全部移到 core 层的 damon_start() 和 damon_commit_ctx()。sysfs 与 module 参数入口不再各自实现校验逻辑,直接信任 core 层的检查结果。(2)具体操作:damon_start() 新增参数测试提交逻辑;damon_commit_ctx() 在应用参数集时发现无效值立即回滚,避免半应用状态;随后移除 sysfs 中 commit_inputs 校验调用、移除 reclaim/lru_sort 中 min_region_sz 的 is_power_of_2() 重复检查、移除 sysfs 区域负大小校验——这些校验 core 层已有。(3)同步提交了另一个 refactor damon_{start,stop,commit}() 系列(RFC v1.1,11 patches),旨在统一简化错误处理:damon_stop() 返回值改为 void(因无人检查返回 0);damon_call() 失败时不再让调用者自行 stop context,而是在 damon_call() 内部等 kdamond 线程完成异步停止后再返回错误。(4)SJ Park 在 cover letter 里概括:目标是做到“一旦返回成功,DAMON 一定在运行;一旦返回失败,DAMON 一定没在运行”——而当前实现 damon_start() 在遇到错误时可能已启动部分 context,调用者无法安全恢复。
**为什么重要:**这是 DAMON 接口设计的一个关键质量提升。此前参数校验分布在三个不同入口(sysfs、reclaim module、lru_sort module),维护困难且容易不一致。统一后 core 层成为唯一校验点,减少了攻击面。错误处理简化则避免了调用者 side effect 处理不当产生的资源泄漏或 double-stop。对 Android GKI 中已包含 DAMON 的场景,降低了厂商复用时的出错概率。
[来源] https://lore.kernel.org/lkml/20260705155600.96555-1-sj@kernel.org/
[来源] https://lore.kernel.org/r/20260705160142.97308-1-sj@kernel.org/
2. DAMON 引入“数据属性监控”新模式,支持用户自定义探针权重
**发生了什么:**SJ Park 又发出了一个 16-patch RFC 系列,引入“attrs-only monitoring”。核心思路:在现有的 access pattern 监控之外,允许用户定义多个 struct damon_probe,每个 probe 带一个 weight 字段,表示用户对该数据属性的关注度。当 probe weight 被设置时,DAMON 自动关闭传统的 access monitoring(不再在 PTE 里写 accessed bit),仅调用 apply_probes() 收集 probe hits。区域合并也改用 probe hits 加权和而不是 nr_accesses。sysfs 下新增 probe/weight 文件供用户配置。
**为什么重要:**这为 DAMON 开辟了“非访问模式”的使用场景。用户不再被锁定在“谁被访问了”这个单一维度上,可以直接采集自定义属性(如冷热数据、I/O 密度、cache miss 率等)并让 DAMON 基于这些属性做区域合并和操作规划。kernel doc 同步更新了设计与用法。虽然还是 RFC,但方向已清晰,后续很可能扩展为 DAMON 的第二监控面貌。
[来源] https://lore.kernel.org/r/20260705205743.98656-1-sj@kernel.org
3. HWPoison:释放溶解后 HugeTLB 页面时只释放健康子页,彻底阻止 buddy 分配 HWPoison 页
**发生了什么:**Jiaqi Yan 发出 v6 系列(5 patches),延续 v5 思路并进入实质合入流程。dissolve_free_hugetlb_folio() 在释放 HugeTLB 页面到 buddy 时不再整体释放,而是逐子页检查 PG_has_hwpoisoned:健康子页正常释放,HWPoison 子页跳过。为此引入 __free_prepared_contig_range() 变体以支持传递 fpi_t 标志。同时为溶解后的大 folio(如 1G --> 262144 个 base page)设置 has_hwpoisoned flag,使得 buddy __free_pages_prepare() 在 split / high-order alloc 时能拒绝该 folio。Andrew Morton 已确认此实现:This seems correct。
**为什么重要:**此前 dissolve 后整个大 folio 被释放给 buddy,buddy 可能将其以 high-order 形式再分配出去——如果某个子页已经 poisoned,拿到该 folio 的消费者读到的是 poisoned 内存,轻则 MCE 信号丢失,重则造成 silent data corruption。该系列彻底阻断了这条路径。后续动态:Andrew 建议在 free_has_hwpoison() 失败时增加个 WARN() —— 作者是否会采纳待观察。
[来源] https://lore.kernel.org/linux-mm/20260705180714.3708947-1-jiaqiyan@google.com/
4. hugetlb:修复 alloc_fresh_hugetlb_folio() 空 nodemask 导致的 crash
**发生了什么:**Sourav Panda 的 v3 补丁修复了 alloc_buddy_hugetlb_folio_with_mpol() 可能向 alloc_fresh_hugetlb_folio() 传递 NULL nodemask 的问题。当 nodemask 为 NULL 时,核心分配例程 __alloc_fresh_hugetlb_folio() 在 gfp_mask |= __GFP_THISNODE 等逻辑中解引用 nodemask 导致 panic。补丁在传递 NULL 的路径上增加 fallback:使用 cpuset 当前节点的 nodemask 或 node_states[N_MEMORY]。Muchun Song 和 Andrew Morton 已 Ack。
**为什么重要:**这是一个直接导致内核 panic 的 bug,触发于特定配置下的 NUMA 分配路径。修复后阻止了空指针解引用,提升 hugetlb 子系统的稳定性。
[来源] https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
5. 为 PMD 级别 swap entry 铺路:softleaf 抽象补齐、迁移配置重构
**发生了什么:**Usama Arif 的 v2 系列(6 patches)继续推进 PMD 级 swap entries。它做了三件事:(1)增加 softleaf_to_pmd() 补齐 PMD 级 leaf entry 的抽象,使 softleaf_to_pte() / softleaf_to_pmd() 对称;(2)提取 mm_prepare_for_swap_entries() 辅助函数,封装将 mm 加入 init_mm.mmlist 的加锁模式;(3)在 pagemap_pmd_range_thp()、change_non_present_huge_pmd()、migrate_vma_collect_pmd() 中,将 softleaf_to_folio() 的调用搬到确认 entry 是 migration/device-private 类型之后,防止在非 migration 的 non-present entry 上错误读取 PFN。(4)将 ARCH_ENABLE_THP_MIGRATION 更名为 ARCH_HAS_PMD_SOFTLEAVES,表明它为 PMD 级 migration 和 device-private 共用基础。
**为什么重要:**这些是 PMD 级 swap entry 的前置清洁。没有这些改动,后续 PMD swap entry patch 就会在 pagemap_pmd_range_thp() 等处 crash。从上周的 v3 全铺开到今天的 v2 重构前置,说明社区对这个方向的评审越来越细。对大页重度用户(数据库、JVM)影响深远。
[来源] https://lore.kernel.org/linux-mm/20260706114320.1643046-1-usama.arif@linux.dev/
6. memcg: zswap setting 遗漏 css_reset 导致 cgroup 残留问题
**发生了什么:**Jiayuan Chen 的 v2 补丁修复 memcg subsystem 的 css_reset() 未重置 zswap 相关参数的问题。此前仅重置了 memory.low/memory.min 等传统控制,当 cgroup 被清空(reset)后重新配置时,zswap 的 max_pool_limit 仍保留旧值,导致新进程意外触发 zswap writeback 或容量限制。
**为什么重要:**zswap 在容器/Serverless 场景下广泛使用,cgroup 销毁释放后残留的 zswap 设置会导致后续租户产生意外行为。修复后 cgroup reset 语义在 zswap 层面也正确执行。zswap 与 Android 无关(Android 用 zram),但容器场景的修复对服务器用户是直接收益。
[来源] https://lore.kernel.org/linux-mm/20260705140133.e0534a0be91346860fd9056f@linux-foundation.org/
7. proactive reclaim 支持冻结检测,避免机器进入 D 状态死锁
**发生了什么:**Richard Chang 提交了一个单补丁 mm: vmscan: abort proactive reclaim early when freezing。在 do_try_to_free_pages() 中,proactive reclaim(由 /proc/sys/vm/compaction_proactiveness 等触发)会在每次 shrink 循环后检查 freezing(),若检测到系统正在 freezer(挂起/hibernation 或容器 freezing),直接返回并中止循环,而不是等待整个 scan 结束。此前只有 direct/kswapd reclaim 有此检查,proactive 路径缺失。
**为什么重要:**缺少 freezing 检查意味着 proactive reclaim 可能在系统 freeze 过程中长时间持有 mmap_lock 或 LRU lock,阻止其他进程进入 suspend,甚至导致 D 状态死锁。补丁简单但关键。
[来源] https://lore.kernel.org/r/20260706081218.3438762-1-richardycc@google.com
8. 两个 nommu 修复:max_map_count 检查缺失、split_vma 错误路径
**发生了什么:**Hajime Tazaki 提交了两个 nommu 修复:(1)do_mmap() 中缺少对 sysctl_max_map_count 的检查,nommu 下可以通过反复 mmap 耗尽 VMA 槽位;补丁加回 if (vma_count >= sysctl_max_map_count) 拒绝。(2)split_vma() 错误路径未正确更新 write iterator 指针,导致后续 munmap() 部分区域时释放的是错误 VMA,造成内核状态不一致。
**为什么重要:**nommu 架构(如 Xtensa、C-Model、某些嵌入式)同样有安全需求和正确性要求。max_map_count 缺失意味着进程可以映射任意多区域,可能用于提权或 exhaustion 攻击。split_vma 路径错误则可能损坏 VMA 链表。
[来源] https://lore.kernel.org/linux-mm/20260705151017.289ed34630b503cdc1def407@linux-foundation.org/
[来源] https://lore.kernel.org/linux-mm/20260705152708.582fd8d87561f600da23c0a7@linux-foundation.org/
9. DAMON 测试中 ensure_file() 路径检查修复
发生了什么:
wang wei 提交的补丁修正了 selftests/damon 中 ensure_file() 函数的路径检查逻辑:原代码在 not_exist 分支中错误地检查 $dir 是否存在,而非目标文件 $file,导致文件存在性验证失效。补丁将 $dir 替换为 $file,使验证正确指向目标路径。该补丁已由 SJ Park 审阅并合入 damon/next 分支,若短期内未进入 mm.git,SJ Park 将提请 Andrew Morton 处理。
为什么重要:
该修复修正了测试中的路径验证错位,使 ensure_file() 能正确检测目标文件是否存在,避免了因检查对象错误导致的测试误判,提升了测试用例的可靠性。
10. DAMON 为 probe 新增 weight sysfs 文件并更新文档
发生了什么: 补丁修复了 selftests/damon 中 ensure_file() 函数在 not_exist 路径下错误检查 $dir 而非 $file 的 bug,已被合入 damon/next 树来源;另有两个补丁分别更新 DAMON ABI 文档与 usage 文档,为新增的 probe weight sysfs 文件添加描述,该文件用于读取和设置 Data Attributes-only Monitoring 的权重来源来源。
为什么重要: 新增的 weight sysfs 文件使 DAMON 的 Attributes-only Monitoring 模式能够通过 sysfs 接口配置 per-probe 权重,提供该模式的配置途径;自测工具中的错误检查逻辑被修正,使 ensure_file() 能正确验证目标文件是否不存在,增强了测试验证的准确性。
11. 将 CONFIG_ARCH_ENABLE_THP_MIGRATION 重命名为 CONFIG_ARCH_HAS_PMD_SOFTLEAVES
发生了什么: 该补丁将 PMD 级迁移条目(migration entry)的架构门控宏从 CONFIG_ARCH_ENABLE_THP_MIGRATION 纯重命名为 CONFIG_ARCH_HAS_PMD_SOFTLEAVES。涉及的架构(x86、arm64、s390、riscv、loongarch 以及 powerpc 的 PPC_BOOK3S_64)和门控语义不变,无功能变化。来源
为什么重要: 新名称更准确地描述该宏控制的是 PMD 表项在软脏页(soft-dirty)和页隔离(leaf)方面的能力,而非仅限 THP 迁移。这为后续引入 PMD 级 swap 条目等特性提供了统一的架构依赖检查,而不依赖于页面迁移机制。来源
12. PMD 页合并竞态讨论
发生了什么: 在 linux-mm 列表中,Ryan Roberts 指出 arm64 线性映射中 PMD 页合并可能不安全:若多个 CPU 对同一 2M 区域的不同 4K 对象并发调用 set_memory_*(),合并操作可能与其他修改 PTEs 的操作竞态。Adrian Barnaś 回复建议在 execmem_force_rw 和 execmem_restore_rox 中使用 &execmem_cache.mutex 进行互斥,或像 x86 那样在 set_memory 级别加锁。Adrian 还怀疑 update_range_prot() 中无锁页表遍历的安全性。
为什么重要: 该讨论揭示了 arm64 线性映射中大页合并的潜在竞态问题,若不解决可能破坏页表一致性,需在合并路径中添加适当的锁保护。
13. DAMON 设计文档添加数据属性仅监控模式说明
发生了什么: 该补丁更新了 DAMON 设计文档,新增「数据属性仅监控」(Data Attributes-only Monitoring)机制说明。该机制允许用户为每个属性探针设置优先级权重,当所有权重之和非零时启用此模式,此时区域调整使用属性加权和替代原有的访问计数器(nr_accesses),并自动关闭访问监控。
为什么重要: 该模式扩展了 DAMON 的监控灵活性,支持仅依赖数据属性组合而非访问频率的监控场景,为用户提供更精细的监控控制能力。
14. proactive reclaim 支持冻结检测
发生了什么: Richard Chang 提交 [PATCH v1] 在 mm/vmscan.c 的 user_proactive_reclaim 路径中增加 try_to_freeze() 检查,当系统进入冻结状态时,try_to_free_mem_cgroup_pages 循环会提前退出,避免因 cgroup 内存回收阻塞冻结过程。
为什么重要: 修复了通过 /sys/fs/cgroup/.../memory.reclaim 触发的 proactive reclaim 在系统冻结时无法被中断的问题,确保电源管理或热插拔等冻结场景的响应性。
15. nommu 修复:vma_iter_prealloc 失败路径的返回值和 region 管理
发生了什么:
Hajime Tazaki 的补丁修复了 nommu 下 do_mmap() 的两个缺陷:
- 当
vma_iter_prealloc()失败时,错误路径error_just_free未将ret设为-ENOMEM,导致do_mmap()返回 0(失败时返回成功)。 - 该路径无条件释放
region结构,但region已通过add_nommu_region()加入全局nommu_region_tree,释放后留下悬空指针,可能在下一次树遍历时引发 use-after-free。
修复方式:正确更新返回值,并将 region 的加入操作移到分配完成后。
为什么重要:
这两个 bug 分别导致内存分配失败时静默返回成功(违背函数预期)和内核内存损坏(UAF)。修复使 nommu 路径的代码更正确、更安全,减少了潜在崩溃和内存破坏风险。
来源
🔧 其它子系统
Block / 存储
- BLKSECDISCARD 零长度 range 导致 page cache 全量无效化:BLKSECDISCARD ioctl 的输入校验补丁。此前 commit 697ba0b6ec4a 修复了 start+len 溢出,但未处理 start=0、len=0 的情况。此时 end=0 通过检查,后续
truncate_bdev_range()调用设置 lend 为UINT64_MAX(“截断到文件末尾”哨兵值),导致整个 page cache 被无效化。该补丁将校验替换为blk_validate_byte_range(),该函数已拒绝零长度 range,同时将对齐检查从硬编码 512 改为bdev_logical_block_size()。来源
ACPI / RAS
RISC-V
- RISC‑V vmemmap hotplug 后的 spurious page fault 修复:Vivian Wang 的 v4 补丁修复
section_activate()填充新 vmemmap 页后未刷 TLB 的问题。RISC‑V 允许缓存 non‑present TLB entries,此行为在某些硬件上会导致 spurious faults。补丁在__populate_section_memmap()的 population 完成后引入vmemmap_populate_finalize()钩子,RISC‑V 端实现该钩子并调用mark_new_valid_map()。同时,有讨论建议用已有的flush_cache_vmap()替代新钩子。来源
Cgroup / CPUSET
Debugging / Tracing
- refcount/per-cpu-refcount 的 final-put tracepoint:Eugene Mavick 提交 4 patches,为
refcount_t(以及其使用的kref)和percpu-ref添加ref_trace_final_puttracepoint,在引用计数归零时触发。tracepoint 记录三个字段:调用者 (caller)、refcounting 函数 (fn)、refcount 对象 (obj)。该 tracepoint 可为调试 use-after-free 问题提供引用计数归零时刻的追踪信息,弥补当前缺乏通用追踪方式的不足。来源
Testing / Selftests
- KSM rmap_walk 性能优化系列讨论 32 位兼容性:该系列当天主要讨论 32 位平台下 union 中 unsigned long 与 age 相关字段对齐可能导致的未清零问题,提交者认为这不会引入实际错误。来源
- pkey 测试重构 v10:Hongfu Li 将 pkey_util.c 进一步清理,统一 assert 和 tracing 基础设施。来源
- mincore: 使用默认 huge page size 测试 hugetlb:Yijia Wang 修复 selftest 中使用 base page size 映射 hugetlb 的问题。来源
Filesystem (f2fs)
- large folio write path for f2fs:extend folio state:Zhao Nanzhe 的 RFC v2 系列为 f2fs 添加
prepare_large_folio_write_begin()等支持。Chao 询问为何 folio 可能没有 private 而仍调用folio_set_f2fs_reference(),作者解释该情形源自prepare_large_folio_write_begin()为全覆盖写跳过分配f2fs_folio_state的优化,并称该设计可能值得讨论。来源
Virtio / Balloon
- virtio_balloon: stats vq 在 DRIVER_OK 之后再 kick:Michael S. Tsirkin 的 v2 修复 init_vqs() 在 virtio_device_ready() 之前 kick stats 队列的 spec 违规。来源
x86
- memcpy_flushcache() 固定大小快速路径扩展:Li Zhe 为
memcpy_flushcache()增加对 32/48/64/80/96 字节大小的 inline 优化,用于 x86_64 上 sizeof(struct page) 的常见值(64、80、96 字节)。reviewer 询问为何不处理 misaligned 目标;Li Zhe 解释 inline 路径仅在对齐时使用,misaligned 时回退到__memcpy_flushcache()更高效,并将在 v6 中补充注释。来源
👀 值得追的讨论 / Patch
userfaultfd: UFFDIO_MOVE 源 PMD 上的等待可靠性
Usama Arif 的补丁修正了 move_pages_huge_pmd() 中 pmd_migration_entry_wait() 的参数传递:将 &src_pmdval 改为 src_pmd。原因是 pmd_migration_entry_wait() 必须锁定并重新读取真实页表 PMD;在 split-PMD-lock 内核上,传递栈地址 &src_pmdval 会导致错误的锁获取,可能引发 wild spinlock 和内存破坏。该补丁由 Rik van Riel 审阅,Sashiko 报告了该问题,补丁添加了 cc:stable。来源
mm/vmalloc: 连续内存 map 合入争议仍存
Wen Jiang 的 v5 系列通过 arm64 hugetlb PTE batching + vmalloc page batched map 加速 vmap/ioremap 路径。v4 中 reviewer 提出 unused “start” 参数问题。v5 意在被合入,但仍有架构合入细节需要达成一致。来源
⚡ 一句话速览
- Pgtable RCU free ptdump UAF 修复讨论持续:David Carlier 提交的 v7 补丁避免 ptdump 遍历时内核页表被释放导致的 UAF,Andrew Morton 回复表示“A use-after-free is something we should attend to!”,并指出 AI review 提到的四个有效问题:init_mm 遍历应使用无锁变体、锁释放需仅针对 init_mm、地址空间顶部溢出问题、以及 RCU 延迟释放未覆盖 powerpc。来源
- Shmem direct swapin livelock 修复 backport:Baolin Wang 为 linux-6.18.y 提交 backport,修复当多个线程并发 swapin 同一 shmem 页面时的 livelock。来源
- migrate_device: 修复在 non-present PTE 上调用 pte_pfn() 和 pte_dirty():Kefeng Wang 修复在
migrate_vma_collect_pmd()中对 non-present 条目(如 swap PTEs)调用pte_pfn()和pte_dirty()的问题,这些函数在 non-present PTE 上行为未定义,可能导致崩溃或错误的 dirty folio 记账。通过添加pte_present()检查来防护。来源 - memcontrol 代码风格清理:Po-Sheng Lin 提交补丁,将 memcontrol 中所有裸
unsigned替换为unsigned int。来源 - PAGEMAP_SCAN 写入状态修复:Kiryl Shutsemau 修复
/proc/self/pagemap的PAGEMAP_SCAN接口 —— 在 scan 未填充的 PTE(pte_none)时,错误地报告了PAGE_IS_WRITTEN状态。来源 - Usama Arif 被加入 THP reviewers:Lance Yang 正式将 Usama Arif 加入 MAINTAINERS 的 THP 审查人名单。来源
- mseal 文档修正讨论:Leon Hwang 提交补丁在 mseal.rst 中说明
mmap_write_lock_killable()可能返回-EINTR。Matthew Wilcox 指出 killable 与 interruptible 的区别,用户空间不会见到-EINTR。Leon 随后表示将删除相关文档变更。来源 - UFFD-WP (RWP) 补丁 v9 经 Sashiko review,Kirill Shutemov 回应并发布 v9.1 测试补丁:仅一个测试补丁需修改,已作为 v9.1 的 14/15 提交。11/15 发现的 PAGEMAP_SCAN 不一致为预存问题(与 RWP 无关),已另发修复。其余发现 Kirill 评估为误报(如 07/15、10/15、13/15)或预存问题(09/15 部分),并逐一解释理由。来源
- Zswap per-memcg 写回 (v5) 讨论持续:社区 reviewer 继续讨论 cgroup v2 支持下 zswap 的 per-memcg writeback 的 NUMA 朋友调度问题。未有新版本发出。[来源](thread 持续,今日单日无新邮件)