
随着云原生和虚拟化基础设施的演进在不中断宿主机上运行的租户虚拟机VM的前提下完成宿主机内核升级Host Kernel Live Update已从“锦上添花”变成了生产环境的刚需。尽管 Linux 内核在 6.19 开发周期中正式合并了零停机升级的基础设施——kexec 切换kexec handover与实时更新协调器live update orchestrator但仍遗留了一个影响性能的核心痛点基于hugetlbfs管理的大页Huge Pages内存尚无法在实时更新过程中存活。在 2026 年 Linux 存储、文件系统、内存管理与 BPF 峰会LSFMMBPF上Pratyush Yadav 提出了补齐这一短板的架构设计力求让 GB 级别的巨页能够在内核重启替换时平滑过渡。一、 架构背景kexec 切换与实时更新协调器要理解 hugetlbfs 保留的难点首先需要看懂 Linux 实时更新的底层分层设计┌─────────────────────────────────────────────────────────┐ │ 运行中的系统 (HOST) │ │ ┌───────────────┐ ┌────────────────┐ │ │ │ QEMU / VM │ │ Live Update │ │ │ │ (进程物理内存) │ │ Orchestrator │ │ │ └───────┬───────┘ └───────┬────────┘ │ │ │ 用户态 │ 用户态 │ ├──────────┼──────────────────────────────────┼───────────┤ │ │ 内存页面 │ 控制指令 │ │ ┌───────▼───────┐ ┌───────▼────────┐ │ │ │ hugetlbfs ├─[冻结与固定]──────►│ Kexec Handover │ │ │ └───────────────┘ └───────┬────────┘ │ │ │ 内核态 │ └─────────────────────────────────────────────┼───────────┘ │ kexec_load() ▼ [ 新内核引导启动 ]整个实时更新机制由两个关键组件协作完成kexec Handover内核子系统纯内核态接口无用户空间 API。负责在kexec重启期间注册并标记需要保留的物理内存区域保证其页面描述符和元数据不被释放。Live Update Orchestrator用户态协调器面向用户态的控制工具。负责协调资源注册、触发状态保存并最终向内核发送kexec_load()系统调用启动新内核。6.19 版本的局限小页 vs 高性能在 6.19 合并的早期版本中kexec handover 仅支持通过memfd_create()创建的共享内存文件。虽然这能勉强带飞虚拟机但由于普通内存页如 4KB存在深刻的页表层级和频繁的 TLB 缺失将虚拟机放在普通memfd中运行性能极差。为了实现最佳性能主流 Hypervisor如 QEMU/KVM通常会向宿主机的hugetlbfs申请2MB 或 1GB的巨页来挂载 VM 内存。而在当前任何挂载在 hugetlbfs 上的虚拟机在宿主机内核更新前都必须关机。二、 解决方案巨页跨内核传递的设计思路Yadav 的设计秉承了一个极其重要的内核原则尽可能减少需要保留的状态Minimal State Preservation。因为任何被保留下来的状态本质上都会变成内核 ABI应用程序二进制接口的一部分保持极简能大幅降低后续内核迭代的维护成本。整个巨页保留流程分为三个关键阶段阶段 1冻结与固定Freezing Pinning在旧内核准备下线前必须锁定目标巨页防止数据在更新期间被修改、迁移Migration或压缩Compaction。社区讨论了两种方案Inode 级别标志位Inode-level Flagging在对应的 hugetlbfs inode 上增加标记类似shmem的做法。但这种方案被部分开发者批评为绕过 VFS 语义的“凑合妥协hack”。地址空间标志位Address-Space Flagging首选在 filemap 层级引入新的 address-space flag。虚拟文件系统VFS层能够显式感知到冻结状态并在任何写入修改发生前将其拦截。锁定标志设置完成后相关物理内存页会被立即Pin固定住。阶段 2元数据序列化旧内核将每个被冻结巨页的关键几何信息包括物理基地址、页面大小、偏移量打包序列化。这个极小的元数据块与被冻结的物理页面一起被标记为“kexec 保留”。阶段 3在新内核中重建恢复当新内核 Boot 完成后内核实例化一个新的基于 hugetlbfs 的memfd文件描述符。将保留下来的物理巨页按照原偏移量重新放回新内核的页面缓存Page Cache中。对 Control-groupcgroup重新进行内存计费。QEMU 进程恢复运行整个过程中 VM 甚至完全没有感知到宿主机内核已经换了一拨人。三、 工程挑战与未解难题将hugetlbfs的状态带过 kexec 重启必然会与 Linux 内存管理的其他子系统产生冲突其中最为突出的有两个问题旧内核启动 新内核启动 ┌───────────────────────────┐ ┌───────────────────────────┐ │ hugetlbfs 预分配 100 巨页 │ │ hugetlbfs 预分配 100 巨页 │ └─────────────┬─────────────┘ └─────────────┬─────────────┘ │ │ ▼ ▼ ┌───────────────────────────┐ ┌───────────────────────────┐ │ 实时更新保留了 20 个巨页 ├────────►│ 恢复旧内核传递来的 20 巨页 │ └───────────────────────────┘ └─────────────┬─────────────┘ │ ▼ ┌───────────────────────────┐ │ 风险巨页过度分配 │ │ (总请求量暴涨至 120 页) │ └───────────────────────────┘挑战 A巨页的“过度分配Over-Allocation”通常情况下hugetlbfs会在内核引导早期根据启动参数如hugepagesN预先分配固定数量的巨页池。如果新内核启动时照常预分配了N个新巨页随后又从 kexec handover 恢复了旧内核传过来的M个保留巨页系统巨页总量就会变成N M。这极易导致系统物理内存被挤爆或引导失败。解决方案新内核在引导极早期检查 kexec handover 的元数据统计出保留巨页的数量M然后自动将本次hugetlbfs的预分配目标相应缩减为N - M。挑战 B与 CMA连续内存分配器的兼容性如果旧内核中的巨页是从 CMAContiguous Memory Allocator区域动态借来的在恢复时就需要将这些页面插回新内核的 CMA 管理区。但现有的 CMA 并不支持在 Boot 后动态扩展或注入既有的物理内存块。当前妥协当前的 Patch 集采取了“一刀切”策略——如果启用了 Live Update直接禁止 hugetlbfs 从 CMA 中获取内存。CMA 的状态保留被留作未来的研究课题。四、 项目进展与未来展望补丁集现状首个 RFC Patch 已经在2025 年 12 月提交至内核邮件列表。在回应首轮反馈的过程中作者发现 kexec handover 本身存在若干底层的架构缺陷目前正在进行重构。下一步计划作者即将在回应完社区意见后发布更新后的 Patch 系列重点完善 VFS 冻结语义。一旦该特性正式合并Linux 宿主机内核的实时更新将真正具备支撑高性能生产级虚拟化Zero-Downtime Hypervisor的能力。