sched discussion
[PATCH] sched/numa: fix stale dst_nid used in distance calculation for candidate nodes
LLM 分析
sched/numa:修复候选节点距离计算使用陈旧 dst_nid 的 bug
系列概况
- 标题: [PATCH] sched/numa: fix stale dst_nid used in distance calculation for candidate nodes
- 作者: Li RongQing lirongqing@baidu.com
- 版本: v1(单 patch,邮件未带版本号)
- 规模: 1 file changed, 1 insertion(+), 1 deletion(-)
- 修改文件: kernel/sched/fair.c(函数 task_numa_migrate)
- 代码统计: +1/-1
- Message-ID: 20260714092110.1722-1-lirongqing@baidu.com
- 完整性: thread 含 1 个 patch + 1 个作者自我 ping 回复,没有 maintainer 公开 review
补丁目的
修正 task_numa_migrate() 在遍历候选 NUMA 节点时,dist 没有用当前候选节点 nid 重新计算,而是复用了上一次迭代留下的 env.dst_nid。结果下游 task_weight() 评分建立在陈旧距离上,NUMA balancing 决策可能把 task 留在次优节点。
旧流程的问题
旧代码:
dist = node_distance(env.src_nid, env.dst_nid);
env.dst_nid 在循环开头是 preferred nid(或上一次迭代选出的最优 nid),被错当成"输入距离参数"使用。每个候选 nid 都被同一个距离打分,违反"为每个候选单独评分"的语义。
新流程
dist = node_distance(env.src_nid, nid);
每轮循环都用当前候选节点 nid 取真实距离,下游 task_weight() 与 if (dist != env.dist) 的比较都基于正确数值。
Patch 概览
- 文件:
kernel/sched/fair.c,函数task_numa_migrate() - 单 hunk 单行修改:
- dist = node_distance(env.src_nid, env.dst_nid);
+ dist = node_distance(env.src_nid, nid);
关键实现
上下文(行 3319 附近):
for_each candidate nid {
if (nid == env.src_nid || nid == p->numa_preferred_nid)
continue;
dist = node_distance(env.src_nid, nid); /* 修复点 */
if (sched_numa_topology_type == NUMA_BACKPLANE &&
dist != env.dist) {
taskweight = task_weight(p, env.src_nid, dist);
...
}
/* 循环末尾把最优 nid 写回 env.dst_nid(仅作输出) */
}
env.dst_nid 在下游被赋值为本次迭代的最优 nid,本应只承担"输出"职责;旧实现却把它当作输入距离参数复用,混用导致 bug。
变量身份示意:
+----------------------+
loop in -->| candidate nid (var) |---+
+----------------------+ |
v
env.dst_nid <----- writes best nid (output slot)
^
|
+-- old code wrongly reads it as input distance
+-- new code no longer uses env.dst_nid for distance
控制流:
task_numa_migrate(p)
|
+-- init env (src_nid, dst_nid=preferred, ...)
|
+-- for each candidate nid:
| |
| +-- nid == src/preferred ? --> skip
| |
| +-- dist = node_distance(src_nid, nid) <-- fix
| | (old: src_nid, env.dst_nid)
| |
| +-- BACKPLANE && dist != env.dist ?
| | taskweight = task_weight(p, src_nid, dist)
| |
| +-- pick best nid -> env.dst_nid (may stay stale)
|
+-- choose final dst and migrate
类比
- 像外卖调度员在几家候选餐厅中选一家下单:旧逻辑下,每看一家新店,他都还在念叨"上一家店离我 5 km",结果所有候选都按 5 km 评分,越选越离谱。新逻辑每看一家都用"这家店离我 X km"打分,决策才靠谱。
- 或者像超市比价,每拿起一件商品都该看自己的价签,而不是抄第一件商品的价格当所有商品的价格。
Highlight:风险与注意点
env.dst_nid同时承担"输入距离参数"与"本次最优 nid 输出槽"两重角色,是经典的"可变变量被复用"陷阱;下游若有代码再读env.dst_nid做距离相关比较,需要复查是否再次踩坑。- 触发条件:NUMA_BACKPLANE 拓扑或任何依赖
dist的task_weight()路径;影响 NUMA 自动平衡的迁移方向,长期可能让 task 停在次优节点。 - patch 没有附带回归测试或 perf 数据,修复收益难以量化;maintainer 通常会要求补充 before/after 指标或 workload 数据。
- 第二封只是作者自我 ping,无 reviewer 反馈,thread 当前处于无人评审状态,需要持续跟进 v2 或新回复。
版本变化
仅一版(v1),无后续版本演进。
一句话总结
一行修复让 task_numa_migrate() 用当前候选 nid 而不是陈旧的 env.dst_nid 计算距离,把 NUMA balancing 评分拉回正确轨道。