1. 背景
Linux 的 HMM(Heterogeneous Memory Management)与 zone device-private 内存机制,允许把设备(GPU 等加速器)的私有内存以「不可被 CPU 直接访问的特殊页」形式纳入内核内存管理,并在 CPU 系统内存与设备内存之间按需迁移页面。然而在本系列提交之前,zone device-private 内存的迁移只支持 PAGE_SIZE(基础页)粒度。这一限制带来两方面的直接代价:其一,以基础页为单位建立与拆除映射导致页表项数量庞大,TLB 压力显著;其二,CPU 与设备内存之间的批量迁移被切分为大量单页操作,迁移吞吐受限、延迟偏高。
与此同时,普通匿名内存早已具备透明大页(THP)能力,而 device-private 内存无法享有同等的大页收益。随着 GPU 统一虚拟内存(SVM)等场景对大块内存迁移的需求增强,弥合这一能力差距成为必要工作。该系列在 Ralph Campbell 早期工作的基础上继续推进,目标是让 zone device-private 内存支持 THP 粒度的迁移与缺页处理,并在设备侧无法分配大页时能够优雅回退到基础页。
2. 作者与参与团队
该补丁系列([v7 00/16] mm: support device-private THP)由 NVIDIA 的 Balbir Singh 作为主要作者提交与维护,工作延续自 Ralph Campbell(NVIDIA) 的早期原型。评审与协作在 linux-mm、dri-devel、linux-kernel 等社区展开,核心参与者包括:
- Andrew Morton:mm 子系统维护者,负责将系列纳入 mm 树/linux-next 并推动合入,协调修复补丁的合入顺序。
- Matthew Brost(Intel):Xe 驱动 SVM 方向,负责在真实 GPU 驱动上集成与压力测试,报告了关键回归。
- Zi Yan(NVIDIA) :THP 拆分与 folio 语义评审,推动
unmapped拆分路径的重构。 - David Hildenbrand(Red Hat,后为 Arm):核心 mm 语义把关,深度参与 s390 回归根因分析,并对补丁的最小化与文档规范提出要求。
- Christian Borntraeger、Claudio Imbrenda(IBM):s390 与 KVM 方向,定位并修复了该系列在 s390x 上暴露的 gmap 缺陷。
- Wei Yang、Lance Yang、Mika Penttilä、Francois Dugast 等:细节评审与测试反馈。
3. 解决方案总体设计
系列由 16 个补丁构成,整体思路是在既有 zone device-private 基础设施上叠加 THP 感知能力,而非另起炉灶,并保证在大页不可用时无缝回退。其关键设计要点如下:
-
迁移接口引入两个新语义标志 。在
migrate_vma流程中新增MIGRATE_VMA_SELECT_COMPOUND(选择并标记待迁移的 compound 页)与MIGRATE_PFN_COMPOUND(标记迁移条目为 compound)。当调用方向migrate_vma_setup()传入MIGRATE_VMA_SELECT_COMPOUND时,migrate_vma_setup()、migrate_vma_pages()、migrate_vma_finalize()全流程按大页迁移处理。 -
源、目标大页能力不一致时支持中途拆分 。当源侧可迁移大页、但目标侧(例如设备)无法分配大页(源、目标在
MIGRATE_PFN_COMPOUND上不一致)时,迁移过程可将 folio 在中途拆分为基础页继续完成,避免整体迁移失败。 -
全链路 THP 与 zone device 感知。PMD 操作、rmap、page vma walk、缺页处理等路径均被扩展为可识别并正确处理 large zone device-private folio 与其对应的非 present PMD 条目。
4. 关键实现
以下按功能域归纳系列中的核心改动:
-
大页 folio 基础设施(
mm/zone_device)新增 large-order zone device folio 的分配例程与辅助函数,用于判断 folio 是否为 device-private 并设置 zone device 私有数据。需要注意的是,zone device-private 的 large folio 不支持普通 THP 的 deferred split / scan 机制。同时将 pgmap 的释放回调由
page_free重命名为folio_free,统一以 folio 为单位管理释放,且对PAGE_SIZE与更高阶页均适用。 -
PMD 操作与 rmap 扩展(
mm/huge_memory、mm/rmap)为 PMD 级操作补充 device-private THP 支持,并扩展 rmap 与迁移逻辑以处理 device-private 迁移条目。这一改动同时收紧了
___pte_offset_map()对非 present PMD 的判定语义------正是该语义变化在 s390x 上暴露了既有缺陷(见第六节)。 -
device-private THP 拆分与迁移(
mm/huge_memory、mm/migrate_device)实现 device-private THP 的拆分、迁移过程中部分映射 folio 的收集处理,以及 zone device 页的 THP 迁移。在需要拆分且页面已处于 unmapped(迁移条目)状态时,早期实现通过在
__folio_split()中散布unmapped分支来复用逻辑;经 Zi Yan 与 Wei Yang 评审后,重构为独立的folio_split_unmapped()辅助函数,把「页面已解除映射、已从 LRU 隔离、拆分后保持锁定」这一特殊语义从主拆分路径中剥离,降低了主路径的复杂度与锁定语义混淆。 -
驱动侧拆分回调(
mm/memremap)引入
zone_device_private_split_cb()回调,在 folio 拆分时通知驱动同步其私有元数据,使设备驱动能够在核心 mm 拆分大页时维持自身状态一致。 -
缺页处理(
mm/memory)为 zone device-private 页新增 THP 级缺页处理路径。
下面是修改后的测试与应用:
-
测试基础设施(
lib/test_hmm、selftests/mm/hmm-tests)增强
lib/test_hmm.c以支持 THP 迁移,新增用于模拟大页分配失败的 ioctl,从而可控地覆盖 folio 拆分回退路径;hmm-tests.c增加了大页迁移、拆分路径、partial unmap / mremap / anon_write 等用例,并新增吞吐量测试。 -
驱动使能(
gpu/drm/nouveau)让 nouveau dmem 代码使用新的 THP 迁移能力,作为首个上游驱动示范。
该系列在实现上对若干位置硬编码了 HPAGE_PMD_NR,但整体保持了阶数无关的通用结构,为后续 mTHP(多尺寸 THP)扩展预留了空间。作者规划的 mTHP 后续方向包括:在测试驱动中引入可允许 THP 阶数的概念、在非 PMD 路径中检测驱动支持的合适阶数、跨阶数迭代选择可迁移的最高阶并完成迁移。
5. 最终效果与合入状态
在作者基于 lib/test_hmm 的本地测试与吞吐量测试中,该系列相较基础页粒度迁移带来了约 350% 的数据传输吞吐提升 与约 80% 的延迟改善,同时降低了页表开销、提升了内存带宽利用率,并在大页不可用时可回退至基础页。可以看到这个数据比较炸裂,Intel Xe 驱动也发布了数据,性能改善很大,所以强烈建议厂商适配下改机制。
合入状态方面,经对内核树核对,引入 folio_split_unmapped() 的提交 cab812d9c964(Balbir Singh,2025-11-14)可由 v6.19-rc1 包含,git tag --contains 显示其存在于 v6.19 及之后所有版本标签。因此该系列在 v6.19 合并窗口进入 Linus 主线 (首次出现于 v6.19-rc1)。相关符号 MIGRATE_VMA_SELECT_COMPOUND、zone_device_private_split_cb、folio_split_unmapped 均已存在于主线 mm/huge_memory.c、mm/migrate_device.c 与 include/linux/ 之中。
v7 系列封面(00/16):https://lore.kernel.org/lkml/20251001065707.920170-1-balbirs@nvidia.com
6. 评审中的关键问题与处置
s390x KVM 回归 :Christian Borntraeger 报告补丁 03 在 linux-next 中导致 s390x KVM 客户机无法启动。David Hildenbrand、Balbir Singh 与 IBM 团队定位到根因:该系列将 ___pte_offset_map() 的判定从 !pmd_present() 收紧后,暴露了 s390 gmap 既有问题------指向 pte 的普通 gmap pud/pmd 条目未设置 present 位,与用户空间 pud 行为不一致。最终由 Claudio Imbrenda 提交独立修复 KVM: s390: Fix missing present bit for gmap puds(在 __gmap_link() 中补上 _SEGMENT_ENTRY),获得 Tested-by/Acked-by/Reviewed-by。Andrew Morton 按建议将该修复排在引入问题的补丁之前合入,以保证 bisect 不被破坏。
Xe SVM 回归 :Matthew Brost 报告在 Xe 驱动 SVM 压力测试中出现随机内核挂起,表现为 hmm_range_fault() 阻塞于 migration_entry_wait_on_locked(),症状为迁移 PTE 被安装但未被清除,且不启用 THP device page 亦可复现。Balbir 建议在含 remove_migration_pmd() 修复的 mm-unstable 上验证并提供可复现的 hmm-tests 用例,该问题属于合入前后持续排查的稳定性事项。
补丁最小化规范 :David Hildenbrand(Arm)在 2026-02 指出补丁 11 无缘由删除了 __split_folio_to_order() 中对 tail page ->private 的 VM_WARN_ON_ONCE_PAGE 防御性检查。Balbir 说明是测试中该值恒为 NULL 而移除,并同意恢复;David 强调补丁应仅做相关改动并记录原因,将在后续 ->private 改造中酌情加回该检查。
7. 补丁清单与链接
v7 系列共 16 个补丁,均由 Balbir Singh 提交,lore 归档链接如下:
相关联的独立修复与前置工作:
- s390 修复
KVM: s390: Fix missing present bit for gmap puds(Claudio Imbrenda):https://lore.kernel.org/lkml/20251017144924.10034-1-borntraeger@linux.ibm.com/ - Ralph Campbell 早期 THP 迁移原型(参考 1):https://lore.kernel.org/linux-mm/20201106005147.20113-1-rcampbell@nvidia.com/
- HMM large folio 前置补丁
mm/hmm: populate PFNs from PMD swap entry(commit10b9feee2d0d)
历史版本(v1--v6)封面链接:
- v2:https://lore.kernel.org/lkml/20250703233511.2028395-1-balbirs@nvidia.com/
- v3:https://lore.kernel.org/lkml/20250730092139.3890844-1-balbirs@nvidia.com/
- v4:https://lore.kernel.org/lkml/20250812024036.690064-1-balbirs@nvidia.com/
- v5:https://lore.kernel.org/lkml/20250903011900.3657435-1-balbirs@nvidia.com/
- v6:https://lore.kernel.org/lkml/20250916122128.2098535-1-balbirs@nvidia.com/
本文档基于邮件线程 [v7 00/16] mm: support device-private THP(2025-10 至 2026-02,共 79 封邮件)及工作区内核树的合入状态核对整理。