0/3 已展开

LLM 分析

sched/numa:修复远程 private fault 的扫描周期

系列概况

  • 标题:[PATCH] sched/numa: Fix scan period for remote private faults
  • 作者:Hongling Zeng zenghongling@kylinos.cn
  • 版本:单封 PATCH,无 vN 标识
  • 规模:1 个 patch,1 个文件(kernel/sched/fair.c),+11/-6
  • 修改文件kernel/sched/fair.c
  • 代码统计:11 insertions(+), 6 deletions(-)
  • Message-ID20260804030731.539809-1-zenghongling@kylinos.cn
  • 完整性:1 patch + 2 reply(评审 + 作者回复,正文被截断)

补丁目的

修复 update_task_scan_period() 中错误的早返回条件。旧条件 local + shared == 0 把"纯远程 private 内存"工作负载(local=0、shared=0、remote>0)误判为"无 fault",导致扫描周期被翻倍放慢。补丁改为 local + remote == 0,只要存在本地或远程 fault,就跳过早返回进入 ratio 评估。

旧流程的问题

  • 纯远程 private 工作负载命中 local + shared == 0,被强制放慢扫描
  • 错失后续 ratio 计算可能带来的更精细调度
  • 旧版注释中 ps_ratio / lr_ratio 两段的语义描述被搞反:注释说 ps_ratio 是"local",实际是 private/shared;注释说 lr_ratio 是"shared",实际是 local/remote

新流程

  • 早返回条件改为 local + remote == 0:只要存在 fault,就进入 ratio 计算
  • 顺手修正两段注释,使其与实际变量名(ps_ratio = private/shared,lr_ratio = local/remote)对齐

Patch 概览

  1. 修改早返回条件:local + shared == 0local + remote == 0
  2. 在条件上方补一段多行注释,说明"Slow down only when no actual faults"
  3. 改写 ps_ratio 分支注释:去掉"local"误述,明确为 private/shared
  4. 改写 lr_ratio 分支注释:去掉"shared"误述,明确为 local/remote

关键实现

/*
 * Slow down if there are no actual memory faults (local + remote == 0),
 * or if previous migrations failed. Otherwise, use the locality ratios
 * to decide whether the scan rate should be adjusted.
 */
if (local + remote == 0 || p->numa_faults_locality[2]) {
    /* idle / failed migration case */
    p->numa_scan_period = min(p->numa_scan_period_max,
                              p->numa_scan_period << 1);
}

if (ps_ratio >= NUMA_PERIOD_THRESHOLD) {
    /*
     * Most memory accesses are private. Slow down NUMA scanning
     * since there is little shared memory to rebalance.
     */
    int slot = ps_ratio - NUMA_PERIOD_THRESHOLD;
    if (!slot)
        diff = slot * period_slot;
} else if (lr_ratio >= NUMA_PERIOD_THRESHOLD) {
    /*
     * Most memory accesses are local. There is no need to
     * do fast NUMA scanning, since memory is already local.
     * Also, shared memory may be moved by other tasks anyway,
     * since other tasks may just move the memory elsewhere.
     */
    int slot = lr_ratio - NUMA_PERIOD_THRESHOLD;
}

关键变量:

  • local = numa_faults_locality[0]shared = [1]remote = [2]
  • ps_ratio = private * NUMA_PERIOD_SLOTS / (private + shared)
  • lr_ratio = local * NUMA_PERIOD_SLOTS / (local + remote)
  • NUMA_PERIOD_THRESHOLD = 7NUMA_PERIOD_SLOTS = 10
                  +-------------------------------+
                  |  update_task_scan_period()    |
                  +---------------+---------------+
                                  |
            +---------------------+---------------------+
            |                                           |
   local+remote==0 OR locality[2]!=0  (no real faults)
            |                                           |
            v                                           v
   +----------------------+            +-------------------------------+
   | DOUBLE scan period   |            | compute ps_ratio, lr_ratio    |
   | (numa_scan_period<<1) |            +---------------+---------------+
   +----------------------+                            |
                                          +-----------+-----------+
                                          |                       |
                                  ps_ratio >= 7 ? ps_ratio < 7  |
                                          |                       |
                                          v                       v
                              +----------------------+   +-------------------+
                              | grow period by       |   | else: speed-up    |
                              | (ps_ratio - 7) slots |   | shrink period     |
                              +----------------------+   +---------+---------+
                                                                |
                                                  lr_ratio >= 7 ?
                                                                |
                                                                v
                                                    +----------------------+
                                                    | grow by (lr - 7)     |
                                                    | slots                |
                                                    +----------------------+

类比

NUMA 扫描器像一个仓库巡检员,按固定间隔去看哪些货架上的货物需要搬运。

旧版规则:"如果今天既没人动本地货架、也没人碰共享货架,就把巡检间隔直接拉长一倍。"问题在于:当巡检员发现隔壁仓库堆满货物(remote private)时,他误以为"今天没动静",干脆把巡检节奏放慢——而这恰恰最应该多巡几次,看看是否要把货物搬回本地。

新版规则改成:"只要有任何货物被访问过(本地或远程),就走精细评估流程,看 local/remote、private/shared 的比例再决定节奏。"巡检员不再被"空货架假象"误导。

Highlight:风险与注意点

  1. Zhan Xusheng 的关键反驳(最重要):commit message 声称去掉早返回后 ratio 计算会"加速扫描",但代码上不成立:
    • 纯 remote private 场景 ps_ratio = private * 10 / (private + 0) = 10永远 >= 阈值 7
    • 仍走 ps_ratio 的"grow by ~3 slots"分支,不是加速
    • 加速分支要求 ps_ratio < 7 && lr_ratio < 7,纯 remote private 永远达不到
    • 实际效果只是把"翻倍"换成"增长 ~3 slots"
  2. 缺数据:评审明确要求 before/after 数字,扫描速率类变更没有数据很难合入
  3. 注释修正应独立成 patch:把 ps_ratio/lr_ratio 注释 cleanup 与行为变更混在一起,让评审难以判断行为变更是否真的需要
  4. 第三封邮件正文被截断:Hongling Zeng 对评审的回复在 lore 抓取中不完整,无法看到他是否回应"效果被高估"和"拆分 patch"两条建议,需回 lore 查完整邮件
  5. numa_faults_locality[2] 语义:补丁隐含假设 index 2 是 remote,需在 fair.c 头/注释中确认以免后续误读

版本变化

本系列仅一个版本(v1),无 vN→vN+1 演进。

一句话总结

修复 update_task_scan_period() 针对纯远程 private 工作负载错误放慢 NUMA 扫描的条件,但评审一针见血指出 commit message 描述的"加速扫描"在代码上并不成立,实际只是把翻倍变成增长 3 个 slot,需要数据支撑并把注释 cleanup 拆成独立 patch。