zone->contiguous:整个 span 的 PFN 都有在线 memmap
struct zone
spanned_pages
contiguous = true
整个 span 连续
compaction 可走快速路径
zone span · 每个 PFN 都要有在线 memmap
任意 PFN 可安全 pfn_to_page()
compaction
逐 pageblock 遍历
pageblock_pfn_to_page()
直接取 page
pfn_to_page()
不再逐页检查
contiguous 为真 → 跳过 pfn_valid() 与 pfn_to_online_page()
改一次 pfn range,就全量重扫一次
memory hotplug
改变 zone 的 pfn range
set_zone_contiguous()
重建连续标志
遍历整个 zone span
pageblock 粒度逐块验证
zone span 按 pageblock 切开
每个 pageblock 只查首尾 PFN
subsection 级 hole 可能漏检
每次 online/offline 都要重扫整个 zone
耗时随 zone 跨度线性增长
只验证首尾 PFN,内部 subsection 级 hole 可能漏检
判定偏宽松,含 small hole 的 zone 也可能被误判连续
struct zone
spanned_pages
pages_with_online_memmap
contiguous
新增:拥有在线 memmap 的页数
判定连续只需要它
zone->spanned_pages
== zone->pages_with_online_memmap
contiguous = true
一次整数比较
否则保持不连续,不触发任何扫描
if (zone->spanned_pages == zone->pages_with_online_memmap)
WRITE_ONCE(zone->contiguous, true);
说明:zone_is_zone_device() 直接返回
启动内存 · memmap_init_zone_range()
memmap_init_range() 初始化 region 内 PFN
全部在线 → 按页数直接累加
init_unavailable_range() 处理 region 之间的洞
pfn_section_valid() 按 subsection map 判定后计入
early section 的页全标记 online
热插拔内存
adjust_present_page_count()
与 present_pages 一起增减
online 加,offline 减
计数器始终增量维护
不需要重新扫描
subsection 大小 2MB
online
offline
online
offline
同一 subsection 内 online 状态一致
判定结果按 subsection 缓存,每段只查一次
memory block online/offline 前后各一次
操作前 clear_zone_contiguous(),操作后 set_zone_contiguous()
move_pfn_range_to_zone / remove_pfn_range_from_zone 的旧扫描删除
计数器只统计落在当前 zone span 内的页
少计是安全的
最坏只是暂时不识别为连续,不影响正确性
section 内按 subsection(2MB)划分
边界
旧:shrink_zone_span() 每个 subsection 只查一个边缘 PFN
边界落在 subsection 中间时,该 PFN 可能属于别的 nid/zone
漏掉 subsection 内合法 PFN → 错误收缩 zone span
修复:同时检查 subsection 首尾两个 PFN
find_smallest_section_pfn() / find_biggest_section_pfn()
online 状态整个 subsection 一致 → 仍只查一次
virtio-mem 热插拔实测
Intel Icelake 服务器 · Guest kernel v7.3-rc3 · QEMU 9.0
操作
内存大小
耗时(上 Before · 下 After)
缩短
热插拔
256G
10s → 3s
70%
热插拔
512G
36s → 7s
81%
热拔除
256G
11s → 4s
64%
热拔除
512G
36s → 9s
75%
耗时口径:QEMU 命令 → /proc/meminfo 反映新内存
该系列同样利好 CXL 热插拔
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x