0/40 已展开

LLM 分析

pghot:把热页跟踪与升级做成跨源统一基础设施

系列概况

  • 标题:[PATCH v8 0/8] mm: Hot page tracking and promotion infrastructure
  • 作者:Bharata B Rao bharata@amd.com(AMD)
  • 版本:v8,2026-07-28 投递;前置 lore 链接显示 v1(2025-08-14)到 v7(2026-05-04)共 8 个公开版本
  • 规模:8 个 patch,跨 mm/、kernel/sched/、arch/x86/ 三大目录;David Hildenbrand 评"diffstat is scary"
  • 修改文件:mm/migrate.c、mm/pghot*.c、include/linux/{pghot.h, migrate.h, mm.h, mmzone.h}、kernel/sched/{core,fair,debug}.c、init/Kconfig、Documentation/admin-guide/mm/pghot.rst、arch/x86/Kconfig、arch/x86/include/asm/{ibs-caps.h, ibs-mprof.h, idtentry.h, irq_vectors.h, msr-index.h, hardirq.h, perf_event.h}、arch/x86/entry/entry_fred.c、arch/x86/kernel/{idt.c, irq.c}、arch/x86/mm/{Makefile, ibs-mprof.c}、Documentation/admin-guide/kernel-parameters.txt
  • 代码统计:pghot.c / pghot-default.c / pghot-precise.c 新文件合计约 300+ 行;ibs-mprof.c 两个 patch 共约 600 行;从 perf_event.h 迁出 81 行 IBS 定义;Documentation/admin-guide/mm/pghot.rst 新建 89 行 + 后续 patch 5/7/8 补充到 196 行
  • Message-ID20260728054356.291998-1-bharata@amd.com(cover letter)
  • 完整性:thread 抓取 40 封;前 9 封为 v8 patch + 5 封 benchmark 数据续贴 + 26 封评审与回信;lore 上还能看到 2026-07-28 至 2026-08-13 的多轮维护者答复

补丁目的

把"hot page 跟踪 + 升级"抽成一个统一子系统 pghot:让多个热度来源(NUMA hint fault、AMD IBS Memory Profiler、未来 CXL HMU/CHMU 等硬件采样器)共享一套 per-PFN 元数据 + 一套 per-lower-tier-node 的 kmigrated 内核线程,把原本散落在 scheduler(fair.c / cpupid 时间折算、rate-limit、pgdat_free_space_enough 等)的 NUMA balancing tiering mode(kernel.numa_balancing=2)路径全部迁到 mm 一侧。v8 关键改动:hot_map 改为 RCU 化的 struct pghot_hot_map;tunable 从 debugfs 切换到 sysctl;AMD IBS Memory Profiler 重做为独立 system interrupt vector 0xea、且拆成基础设施 / runtime controls 两个 patch;hint faults 来源修复若干细节。

旧流程的问题

  1. v7 之前的 per-section hot_map 通过把 section 热标志塞在指针最低位实现,并发读取与 map 拆解之间锁细节冗长;v8 改为 RCU 保护的 struct pghot_hot_map,热标志迁到结构体内 flags 字段,kfree_rcu 释放,规避低位指针技巧的并发裂缝。
  2. kernel.numa_balancing=2 的速率限制、cpupid 时间折算、pgdat_free_space_enoughnuma_hint_fault_latency 等热页提升逻辑长期占用 kernel/sched/fair.ckernel/sched/debug.c 的若干节流路径;v8 把它们迁出 scheduler,挂到 pghot+CONFIG_NUMA_BALANCING_TIERING 下,仅留 numa_balancing_promote_rate_limit_MBps 做兼容 alias。
  3. AMD IBS Memory Profiler 早期版本依赖 perf 子系统并走 NMI handler;v8 完全脱离 perf,改成 0xea 系统中断向量 + per-CPU ring buffer + 自有 bottom-half 线程,但需要把 IBS CPUID/Macro 等 bit 定义外置到独立 ibs-caps.h,避免新 driver 因 include perf_event.h 而背依赖。

新流程

                          +-----------------------------+
                          |  hotness sources            |
                          |  - hint faults (NUMAB2)     |
                          |  - hardware hints (IBS)     |
                          |  - (future) CHMU / HMU      |
                          +--------------+--------------+
                                         |
                                         v
                          +-----------------------------+
                          |  pghot_record_access(pfn)   |
                          |  per-section pghot_hot_map  |
                          |   (RCU, phi_t[])            |
                          +--------------+--------------+
                                         | bit MSB set => migrate-ready
                                         v
                          +-----------------------------+
                          |  per-node kmigrated thread  |
                          |  scan lower-tier PFNs       |
                          |  rate-limited + batched     |
                          +--------------+--------------+
                                         |
                                         v
                          +-----------------------------+
                          |  promote_misplaced_memcg_   |
                          |  folios() -> migrate_pages  |
                          |  -> higher tier node        |
                          +-----------------------------+
Default phi_t (1 byte):
  +---+---+---+---+---+---+---+---+
  | F | F | T | T | T | T | T | R |
  +---+---+---+---+---+---+---+---+
    freq(2)   time bucket(5)   ready(1)

Precision phi_t (4 bytes, u32):
  +---+---+---+---+---+---+---+---+---+---+---+---+
  |      NID(10)     | F(3) |     Time(14)    | R |
  +---+---+---+---+---+---+---+---+---+---+---+---+
                    freq           time        ready

Patch 概览

#主题主要落点
1/8mm: migrate: Allow misplaced migration without VMAmigrate_misplaced_folio_prepare() 允许 vma == NULL,为内核线程上下文迁移铺路
2/8mm: migrate: Add promote_misplaced_memcg_folios()引入批量化 misplaced 提升接口(同 memcg 强约束),Gregory Price 原作
3/8mm: Hot page tracking and promotion - pghotpghot 主体:sysctl/debugfs、RCU hot_map、kmigrated、NUMA hint-fault 旁路
4/8mm: pghot: Precision mode for pghotCONFIG_PGHOT_PRECISE:4 字节/PFN,含 NID/Freq/Time/Ready
5/8mm: sched: move NUMA balancing tiering promotion to pghotkernel.numa_balancing=2 tiering 路径迁到 pghot;numa_balancing_promote_rate_limit_MBps 保留为兼容 alias
6/8x86/ibs: Move IBS caps definitions into its own header81 行 bit/mask 定义从 asm/perf_event.h 外迁到 asm/ibs-caps.h
7/8x86/mm/ibs: In-kernel driver for AMD IBS Memory Profiler系统中断向量 IBS_MEMPROF_VECTOR=0xea、5 个 MSR、per-CPU ring buffer、bottom-half worker
8/8x86/mm/ibs: Add runtime controls for IBS memprofilersysfs /sys/devices/system/cpu/ibs-mprof/enabled + debugfs ibs-mprof/{l3miss-only,period,lat-filter,lat-thresh},双槽 smp_store_release/load_acquire 配置发布

关键实现

  • struct pghot_hot_map:每 mem_section 一份,含 struct rcu_head rcuunsigned long flags(目前只承载 PGHOT_SECTION_HOT_BIT)、flexible phi_t phi[];由 mem_section->hot_map 用 RCU 指针引用,map 释放走 kfree_rcu(),读取侧在 rcu_read_lock() 下做指针解引用,把"section 是否热"从指针 LSB 中独立出来。
  • phi_t:默认 1 字节 = [Freq(2)][TimeBucket(5)][Ready(1)];精度模式扩到 u32 = [NID(10)][Freq(3)][Time(14)][Rsv(4)][Ready(1)]pghot_update_record() 使用 try_cmpxchg 循环做无锁读改写,PCPU 读到的记录保持顺序一致。
  • kmigrated:每个 lower-tier node 一个内核线程,按 kmigrated_sleep_ms(默认 100ms)周期扫描,kmigrated_batch_nr(默认 512)限制批次,walk 时在 rcu_read_lock() 内调 folio_memcg();命中 migrate-ready 位 + freq_threshold 的页通过 promote_misplaced_memcg_folios() 异步批迁移。
  • migrate_misplaced_folio_prepare(folio, vma=NULL, node)vma == NULL 时跳过 (VM_EXEC && folio_maybe_mapped_shared) 检查(内核线程没有 VMA),且不再要求持 PTL;保留 migrate_misplaced_folio() 单页路径,给 hint-fault 路径调用 migrate_misplaced_folio_prepare + promote_misplaced_memcg_folios() 双步走。
  • NUMA hint-fault 旁路do_numa_page() / do_huge_pmd_numa_page() 在 NUMAB2 tiering 模式下用 folio_is_promo_candidate() 替代直接迁移,对共享 EXEC folio 在 hint-fault 时直接 nid = NUMA_NO_NODE 过滤掉(VMA 在 kmigrated 批迁移时拿不到),再把事件喂给 pghot_record_access()
  • NUMA balancing tiering 搬迁init/Kconfig 新增 CONFIG_NUMA_BALANCING_TIERING(depends on NUMA_BALANCING && PGHOT);kernel/sched/core.cset_numabalancing_state 中仅在开启 tiering 时做迁移复位;fair.csysctl_numa_balancing_promote_rate_limitpgdat_free_space_enoughnuma_hint_fault_latency 等被删除。
  • AMD IBS Memory Profilerarch/x86/KconfigAMD_IBS_MEMPROFdepends on PGHOTselect HWMEM_PROFILERIDT 注册 INTG(IBS_MEMPROF_VECTOR, asm_sysvec_ibs_memprof),新增 0xc0010380..0xc0010385 六条 MSR;中断入口 mprof_overflow_handler 读取 dcmiss/paddr valid 样本,写到每 CPU mprof_sample_pcpu ring(head/tail 用 smp_store_release/smp_load_acquire 配对);bottom-half mprof_worker 线程调 pghot_record_access() 喂数据;mprof_publish() 用配置双槽 + on_each_cpu() 发到所有 CPU。
  • Runtime controls:sysfs /sys/devices/system/cpu/ibs-mprof/enabled 总开关;debugfs ibs-mprof/l3miss-only(默认 1)、period(5000-134217727,默认 10000)、lat-filter(默认 0)、lat-thresh(0-0xf,默认 0);配置快照用 mprof_config mprof_cfg_slots[2] + smp_store_release(&mprof_cfg, slot),热路径仅 smp_load_acquire,不需要持锁。
/* mm/pghot-precise.c (simplified) */
bool pghot_update_record(phi_t *phi, int nid, unsigned long now)
{
    phi_t time = now & PGHOT_TIME_MASK;
    nid = (nid == NUMA_NO_NODE) ? sysctl_pghot_target_nid : nid;
    old_hotness = READ_ONCE(*phi);
    do {
        old_freq = (old_hotness >> PGHOT_FREQ_SHIFT) & PGHOT_FREQ_MASK;
        old_time = (old_hotness >> PGHOT_TIME_SHIFT) & PGHOT_TIME_MASK;
        if (pghot_access_latency(old_time, time) > sysctl_pghot_freq_window)
            freq = 1;
        else if (old_freq < PGHOT_FREQ_MAX)
            freq = old_freq + 1;
        hotness = (nid & PGHOT_NID_MASK) << PGHOT_NID_SHIFT;
        hotness |= (freq & PGHOT_FREQ_MASK) << PGHOT_FREQ_SHIFT;
        hotness |= (time & PGHOT_TIME_MASK) << PGHOT_TIME_SHIFT;
        if (freq >= sysctl_pghot_freq_threshold)
            hotness |= BIT(PGHOT_MIGRATE_READY);
    } while (!try_cmpxchg(phi, &old_hotness, hotness));
    return !!(hotness & BIT(PGHOT_MIGRATE_READY));
}

类比

把 pghot 比作图书馆的"热门书架调度":每本书(即每个 PFN)夹一张借阅小卡(phi_t),上面记录最近被翻的频率和时间,多个入口(hint-fault 借阅反馈台 / IBS 自动借阅计数器 / 未来的 CHMU 摄像头)都能更新小卡;夜班理货员 kmigrated 定期巡架,把超过借阅阈值的书搬到门口最顺手的位置(DRAM top tier)。原本分散在各部门(scheduler、HWLOC、perf)的"借阅规则"统一交还给"理货部"。

Highlight:风险与注意点

  1. diffstat / 维护者链断裂:David Hildenbrand 直接指出 v8 仍无任何 Reviewed-by/Acked-by,跨 mm/sched/x86 三棵树;arch 部分需要 x86 maintainer ack;建议退回 RFC。这是对当前 v8 最致命的合并门槛。
  2. DAMON vs pghot 路线分歧:Andrew Morton、Matthew Wilcox、SJ Park 连续质疑"为何不直接用 DAMON"。pghot 是 per-PFN 精确记录 + 内核强制策略,DAMON 是区域采样 + 用户态 DAMOS 策略。是不是真的需要两套并行的 hot-page 提升机制仍未有共识。
  3. 粒度之争:Matthew Wilcox 直言 per-page 是 "too much damn information to track",举 LLC 只有约 512MB 为例,认为应在 2MB / 1GB 边界做;当前 pghot 在 1TB lower-tier 元数据开销 256MB(默认)至 1GB(精度模式),且 pghot_record_access 频次正比于页面访问强度。
  4. AI-slop 风险:Bharata 提交了一份"由 AI 选 DAMON tunables 并跑数据"的对比,SJ Park 直接拒绝审阅,称之为 AI slop;任何 DAMON/pghot 对比必须人类真正理解 DAMON 语义再写。
  5. CHMU/HMU 等无 NID 源:CXL 3.2 CHMU 不告诉访问来自哪个 CPU NUMA node,当前 pghot precision mode 的 per-PFN NID 字段无法直接覆盖 CHMU,需要在 get_record 时回退到全局 pghot_target_nid
  6. 编译依赖缺口:评审指出 pghotCONFIG_NUMA_BALANCING 关闭但 CONFIG_PGHOT 开启时,kmigrated_promotion_rate_limit() 仍访问 pgdat->nbp_rl_start(受 NUMA_BALANCING 保护),需把 rate-limit 内部数据/接口完整放在 NUMA_BALANCING_TIERING 编译保护下。
  7. IBS Memory Profiler 中断路径顺序mprof_pop_sample() 把非 volatile 的结构体赋给 *s 后再 WRITE_ONCE(pcpu->tail, next),编译器可能重排——一旦硬件中断恰好在 tail 推进后抢占 worker,可能观察到"前进的 tail + 正在写的旧样本",需要 smp_store_release(&pcpu->tail, next)。CPU hotplug offline 时 stop_machine 会抢占 mprof_work_handler,被抢占 worker 迁移到其它 CPU 后可能用旧 tail 重写,把新建的空 ring 当成满的旧样本。
  8. 配置 publish 与 hotplugmprof_publish() 用双槽 + on_each_cpu() 同步推所有 CPU,但 mprof_enable_profiling() 在中断 fast-path 中通过 smp_load_acquire(&mprof_cfg) 读快照,CPU online/offline race 时配置槽可能短暂无快照。
  9. CHMU 与 DAMON 融合可能性:SJ Park 在晚回复中提到 DAMON 也在做"access check primitives other than page table accessed bit"扩展,CHMU 可作为新 primitive;pghot 的 hotness 来源设计要保留至少一个"接口抽象层"以便与 DAMON 共享同一硬件后端。

版本变化

  • v7 -> v8:hot_map 改为 RCU 化的 struct pghot_hot_map,section hot flag 改在结构体内;tunable 从 debugfs 迁到 sysctl(只保留 kmigrated_sleep_ms / kmigrated_batch_nr 于 debugfs);AMD IBS Memory Profiler 改为 0xea 系统中断向量而非 NMI,driver 与 perf 完全解耦,拆为基础设施(patches 6/7)+ runtime controls(patch 8);hint-faults 来源增加 (VM_EXEC && folio_maybe_mapped_shared)do_numa_page()/do_huge_pmd_numa_page() 的过滤;保留 numa_balancing_promote_rate_limit_MBps 作为兼容 alias。
  • 前序版本(lore 链接):v1(2025-08-14)至 v7(2026-05-04)系列在 lore.kernel.org/linux-mm/ 上能看到 cover letters 与各版变更日志。
  • 关联系列lore.kernel.org/linux-mm/20260525225208.1179-1-sj@kernel.org/(SJ Park 提出的 CHMU + DAMON 接入路径)被视为 pghot 之外的另一条 hotness monitoring 路线,作者已经在两方向之间搭起软连接。

一句话总结

pghot v8 把 NUMA-tiering 路径与未来硬件采样源在 mm 侧整合成统一 per-PFN hotness + per-node kmigrated 体系;thread 的冲突点在 DAMON 路径重叠、per-page 元数据开销、arch 维护者尚未给 Ack,Bharata 同意退回到 RFC 路径重做讨论。