NUMA-03 页是怎么在 node 间搬家的:内核 NUMA 与页迁移机制

发布时间:2026/7/31 8:21:45

NUMA-03 页是怎么在 node 间搬家的:内核 NUMA 与页迁移机制
NUMA一段内存到底在哪个 node用户态 NUMA 编程接口在用户态调move_pages把页迁到某个 node一行就返回了。但内核里到底发生了什么“目标 node” 这个参数又是怎么一路传下去、最终决定新页落在哪的这一章把这条链路走一遍。1. 内核怎么描述 NUMA 拓扑1.1 每个 node 一个pg_data_t内核给每个 NUMA node 维护一个pg_data_ttypedef 自struct pglist_data里面挂着这个 node 的所有物理页、空闲链表、回收水位线等。通过NODE_DATA(nid)就能拿到第nid个 node 的这个结构。可以把它理解为“每个内存孤岛的户口本”。1.2 CPU 属于哪个 nodecpu_to_node()用户态的numa_node_of_cpu()在内核对应的是cpu_to_node()声明在include/linux/topology.h// include/linux/topology.h#ifndefcpu_to_nodestaticinlineintcpu_to_node(intcpu){returnper_cpu(numa_node,cpu);}#endif每个 CPU 有一个 per-cpu 的numa_node变量启动时由固件ACPI SRAT/SLIT填好。numa_node_id()则是“当前正在执行的 CPU 属于哪个 node”first-touch 分配就是靠它决定新页落在哪。1.3 node 之间有多远node_distance()与那个 “10”在前面文章中反复出现的 distance10它的定义就在内核里include/linux/topology.h// include/linux/topology.h#defineLOCAL_DISTANCE10#defineREMOTE_DISTANCE20#ifndefnode_distance#definenode_distance(from,to)((from)(to)?LOCAL_DISTANCE:REMOTE_DISTANCE)#endif这就是为什么cat node0/distance永远从10起步——LOCAL_DISTANCE硬编码为 10。真实机器上架构相关的node_distance()x86 是__node_distance()读固件 SLIT 表会给出更细的值比如同 socket 内12、跨 socket32。固件 ACPI 表SRAT谁属于谁 SLIT两两距离内核启动解析每 node 一个 pg_data_t每 CPU 的 numa_node距离矩阵node_distance(a,b)内核 APINODE_DATA / cpu_to_node / node_distance一句话用户态在 sysfs 看到的那些 node 与 distance本质是内核把固件表解析成pg_data_t 距离矩阵后暴露出来的。2. 普通页迁移主流程migrate_pages()2.1 从 syscall 到核心函数用户态move_pages(2)进内核后的调用链均在mm/migrate.cSYSCALL_DEFINE6(move_pages, ...) // mm/migrate.c └─ do_pages_move() // 逐页处理把要迁的页收集成 pagelist └─ migrate_pages(pagelist, alloc_migration_target, ...) // 迁移引擎 └─ alloc_migration_target() // 在“目标 node”上分配新页migrate_pages()是内核统一的迁移引擎页面规整、内存热插拔、NUMA balancing、move_pages都复用它。它本身不决定“迁到哪”而是把“怎么分配目标页”交给一个回调——这正是目标 node 进入的入口。2.2 目标 node 是怎么“决定页落点”的看回调alloc_migration_target()mm/migrate.c的关键几行*// mm/migrate.c alloc_migration_target()structmigration_target_control*mtc(void*)private;intnidmtc-nid;if(nidNUMA_NO_NODE)nidfolio_nid(src);// 没指定就落回“源页所在 node”// ... 之后用 nid 去对应 node 上分配新 foliomtc-nid就是“目标 node”。它有值新页就在那个 node 上分配它是NUMA_NO_NODE就退回源页所在 node。用户态传的nodes[i]k一路封装进mtc-nid最终在这里把页落到 node k。这条线索至关重要要让“迁回 CPU 落到最近 node”本质就是让某个nid/mtc-nid等于那个最近 node。2.3 迁移的四步骨架不论哪条路径migrate_pages()内部都是同一套四步① 隔离把源页从 LRU 摘下、锁定② 分配目标页在目标 node 上alloc_migration_target③ 拷贝重映射复制内容、迁移页表项、更新引用④ 收尾释放源页 / 失败则回滚关键点迁移期间要冻结对该页的访问通过锁和页表失效拷贝完成后把指向源页的 PTE 改指向新页。对使用者透明——虚拟地址不变物理页换了个 node。3. 设备内存迁移migrate_vma_*三段式普通migrate_pages()处理的是“普通 CPU 页 ↔ 普通 CPU 页”。但 GPU 显存是以ZONE_DEVICE形式存在的“设备私有页”下一章展开CPU 不能直接访问普通迁移引擎搬不动它。于是内核提供了一套专门的migrate_vma三段式声明在include/linux/migrate.h实现在mm/migrate_device.c。3.1 三个函数// include/linux/migrate.hintmigrate_vma_setup(structmigrate_vma*args);// 实现在 mm/migrate_device.c:735voidmigrate_vma_pages(structmigrate_vma*migrate);voidmigrate_vma_finalize(structmigrate_vma*migrate);调用顺序固定setup → 驱动填 dst → pages → finalize。migrate_vma_setup()收集源页、隔离、冻结映射填 src[] 数组驱动侧为每个源页分配目标页填入 dst[]migrate_vma_pages()逐页拷贝内容、建立新映射migrate_vma_finalize()释放源页、解冻、收尾“分配目标页、填dst[]”这一步在驱动手里——CPU→GPU 时驱动分配显存页GPU→CPU 时驱动或内核 helper分配普通 CPU 页。“迁回 CPU 该落哪个 node”正是在这一步、由分配目标页时选的 node 决定的。3.2struct migrate_vma迁移的“工单”真实结构include/linux/migrate.h// include/linux/migrate.hstructmigrate_vma{structvm_area_struct*vma;unsignedlong*dst;// 目标页 pfn 数组驱动填unsignedlong*src;// 源页 pfn 数组setup 填unsignedlongcpages;// 收集到的可迁移页数unsignedlongnpages;// 地址范围内的总页数unsignedlongstart,end;// 迁移的虚拟地址范围void*pgmap_owner;// 设备私有内存的 owner用于识别“是不是我的页”unsignedlongflags;// 方向选择见下structpage*fault_page;};flags用enum migrate_vma_direction指定迁移方向include/linux/migrate.henummigrate_vma_direction{MIGRATE_VMA_SELECT_SYSTEM10,// 选普通系统内存页MIGRATE_VMA_SELECT_DEVICE_PRIVATE11,// 选设备私有页GPU→CPU 用MIGRATE_VMA_SELECT_DEVICE_COHERENT12,MIGRATE_VMA_SELECT_COMPOUND13,};GPU 显存迁回系统内存时setup用MIGRATE_VMA_SELECT_DEVICE_PRIVATE把设备页挑出来驱动再为它们分配普通页填进dst[]——填dst[]时用哪个 node 分配就是本系列要改对的那个点。4. 内存策略在内核的落地struct mempolicy用户态的set_mempolicy/mbind在内核对应struct mempolicymm/mempolicy.cinclude/linux/mempolicy.h它记录modeBIND/PREFERRED/INTERLEAVE 等和一个nodemask。分配路径alloc_pages_*会读当前生效的 policy决定从哪个/哪些 node 拿页。mbind带MPOL_MF_MOVE时的迁移同样走migrate_pages()只是目标 node 由 policy 的nodemask给出回调alloc_migration_target_by_mpol()mm/mempolicy.c。所以“策略”和“迁移”在内核是解耦的策略负责算出目标 node迁移引擎负责把页搬过去。set_mempolicy / mbindstruct mempolicy(mode nodemask)move_pages(nodes[k])mtc-nid kmigrate_pages() 引擎在目标 node 分配新页页落点 传入的 nid把三层串起来看“目标 node”这个参数的旅程层谁指定目标 node代码锚点用户态move_pages的nodes[]/ mempolicy 的 nodemask第 02 章内核迁移引擎mtc-nid普通页/ 驱动填的dst[]设备页mm/migrate.c、mm/migrate_device.c分配落点nid NUMA_NO_NODE ? folio_nid(src) : nidalloc_migration_target()结论页落到哪个 node从头到尾由一个显式的 node id 决定没人显式指定时才退回“源页所在 node”这个默认。GPU 显存迁回 CPU 属于设备页路径第 3 节三段式落点由驱动填dst[]时选的 node 决定——这正是下一章HMM/ZONE_DEVICE和后续 KFD/DRM 分析时要深入的地方。5. 本章小结内核把固件 ACPI 表解析成pg_data_t每 nodecpu_to_node()每 CPUnode_distance()距离矩阵。distance 的10来自include/linux/topology.h的LOCAL_DISTANCE是硬编码基准。普通页迁移走migrate_pages()四步引擎目标 node 经mtc-nid传入alloc_migration_target()是决定页落点的关键一行。设备页GPU 显存迁移走migrate_vma_setup/pages/finalize三段式落点由驱动填dst[]时选的 node 决定。struct mempolicy负责“算目标 node”migrate_pages负责“搬”两者解耦。关联阅读设备页面迁移migrate_vma 三阶段操作协议

相关新闻

Java集合框架深度解析:从底层原理到高并发实战优化

Java集合框架深度解析:从底层原理到高并发实战优化

2026/7/31 8:21:45

1. 集合,Java开发的基石与“瑞士军刀”如果你写过Java代码,那么你几乎不可能没碰过集合。无论是从数据库查出来的一堆用户对象,还是临时存放几个配置项,集合都是我们最顺手、最常用的工具。但正因为太常用了,很多人对它…

WeChatExporter终极指南:三步轻松备份微信聊天记录,永久保存珍贵回忆

WeChatExporter终极指南:三步轻松备份微信聊天记录,永久保存珍贵回忆

2026/7/31 8:11:45

WeChatExporter终极指南:三步轻松备份微信聊天记录,永久保存珍贵回忆 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 还在为微信聊天记录无法完整…

别再踩坑!6 款主流 AI 代码 Agent 工具完整对比:Claude Code / OpenCode / OpenClaw / OpenClaude / Codex / Trae 一文分清

别再踩坑!6 款主流 AI 代码 Agent 工具完整对比:Claude Code / OpenCode / OpenClaw / OpenClaude / Codex / Trae 一文分清

2026/7/31 8:11:45

很多开发朋友最近在用 AI 辅助本地项目开发,但面对一堆名称高度相似的工具一头雾水:Claude Code、OpenCode、OpenClaw、OpenClaude、Codex、Trae…… 名字看着相近,功能、协议限制、适配模型、国内可用性天差地别。不少开发者花费大量时间配置…

C++内存管理进阶:从原理到实战,掌握智能指针与性能优化

C++内存管理进阶:从原理到实战,掌握智能指针与性能优化

2026/7/31 9:32:09

1. 项目概述:从“能用”到“精通”的必经之路如果你已经写过一些C程序,用过new和delete,也大概知道指针是什么,那么恭喜你,你已经跨过了C编程的第一道门槛。但接下来,你可能会遇到一些更“诡异”的问题&…

从GPT-2到Qwen2:预训练目标函数演进史,及微调阶段必须重写的3个Loss层(附梯度流可视化对比图)

从GPT-2到Qwen2:预训练目标函数演进史,及微调阶段必须重写的3个Loss层(附梯度流可视化对比图)

2026/7/31 9:32:09

更多请点击: https://codechina.net 第一章:从GPT-2到Qwen2:预训练目标函数演进史,及微调阶段必须重写的3个Loss层(附梯度流可视化对比图) 预训练目标函数的演进并非线性叠加,而是由建模假设、…

3分钟掌握视频转PPT神器:一键提取视频中的幻灯片内容

3分钟掌握视频转PPT神器:一键提取视频中的幻灯片内容

2026/7/31 9:32:09

3分钟掌握视频转PPT神器:一键提取视频中的幻灯片内容 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾经为从教学视频、会议录像中手动截取PPT而烦恼?…

AI写测试=替代工程师?资深QA总监的12项不可替代能力清单(2024最新认证标准)

AI写测试=替代工程师?资深QA总监的12项不可替代能力清单(2024最新认证标准)

2026/7/31 9:32:09

更多请点击: https://codechina.net 第一章:AI写测试替代工程师?资深QA总监的12项不可替代能力清单(2024最新认证标准) 当AI生成测试用例的准确率突破92%(据IEEE 2024 QA Survey),真…

网络掩码实战指南:从IP规划到ACL配置的深度解析

网络掩码实战指南:从IP规划到ACL配置的深度解析

2026/7/31 9:32:09

1. 从“16位的掩码”说起:网络工程师的日常与基本功 看到“16位的掩码”这个标题,很多刚入行的网络工程师或者正在备考认证的朋友可能会心一笑,或者眉头一皱。这看起来是一个再基础不过的概念&a…

突发,TRD陷入论文工厂事件!

突发,TRD陷入论文工厂事件!

2026/7/31 9:22:01

近日,有网友发现,一篇2024年发表于《Transportation Research Part D: Transport and Environment》的文章,其图片、表格和公式与2022年《Atmosphere》上的一篇论文高度相似。(左:TRD涉事论文 右:Atmosp…

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

2026/7/30 9:53:22

目标:电脑作为RTSP 服务端,循环推送 H264/H265 视频流; RDK X5 通过 rtsp2display 拉流预览,完全不需要在开发板编译 live555。 提供两套成熟方案: ✅ 方案 A:FFmpeg(最简单,优先推…

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

2026/7/30 1:17:46

一、背景与测试方案 在实际项目交付中,PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及:多源PDF的文件流合并、页面级水印渲染(含透明度混合与图层叠加)、输出文件体积控制。看似简单的操作…

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

2026/7/30 2:52:37

说实话,提到PDF拆分再压缩,我真是被折腾得够呛。 上个月公司年度合同归档,一份300多页的PDF总合同,需要按年份拆分成三个独立文件,再分别压缩到10MB以内方便邮件发送各部门确认。我心想这还不简单?先找个海…

2026优质EMBA择校榜单:校友圈质量高的EMBA适配民企创始人

2026优质EMBA择校榜单:校友圈质量高的EMBA适配民企创始人

2026/7/31 0:01:23

【客观独立测评】深耕商科教育测评多年,聚焦民企创始人、科创企业实控人择校痛点,避开镀金空壳、课程脱节、圈层杂乱的踩坑问题,结合真实办学数据与学员口碑,整理出适配实业高管的高性价比EMBA榜单,理性分析各项目适配…

绝区零一条龙:5分钟快速上手的终极自动化助手

绝区零一条龙:5分钟快速上手的终极自动化助手

2026/7/31 0:01:23

绝区零一条龙:5分钟快速上手的终极自动化助手 【免费下载链接】ZenlessZoneZero-OneDragon 绝区零 一条龙 | 全自动 | 自动闪避 | 自动每日 | 自动空洞 | 支持手柄 项目地址: https://gitcode.com/gh_mirrors/ze/ZenlessZoneZero-OneDragon 绝区零一条龙是一…

2026民企老板EMBA择校榜单:人脉圈广的EMBA高性价比测评

2026民企老板EMBA择校榜单:人脉圈广的EMBA高性价比测评

2026/7/31 0:01:23

【客观中立测评声明】本文基于学费成本、课程落地、圈层纯度、长期赋能四大维度实测打分,无商业洗脑吹捧,仅为民企创始人、科创高管提供真实择校参考,规避镀金踩坑陷阱。不少民营企业家读EMBA容易踩两大坑:盲目追名校排名&#xf…