0/20 已展开

LLM 分析

sched/cache:让 active load balance 真正遵守 migrate_llc_task 语义

系列概况

  • 标题:[PATCH v2] sched/cache: honor migrate_llc_task semantics in active load balance
  • 作者:Lu Wang <wanglu.priv@gmail.com>(合作者:Chen, Yu CTim Chen
  • 版本:v1(2026-08-01)→ v2(2026-08-09);thread 中只有这两个版本,中间经过 4 轮 review
  • 规模:v1 修改 2 个文件,+23/-3;v2 修改 1 个文件,+50/-6
  • 修改文件:kernel/sched/fair.ckernel/sched/sched.h(v1);kernel/sched/fair.c(v2)
  • 代码统计:v1 23 insertions(+), 3 deletions(-);v2 50 insertions(+), 6 deletions(-)
  • Message-ID:20260801122252.2476258-1-wanglu.priv@gmail.com(v1)、20260809105343.1189051-1-wanglu.priv@gmail.com(v2)
  • 完整性:thread 含 v1 patch、v2 patch、两轮 review、Reviewed-by 与一条 commit log 润色建议;流程闭合,未合入状态待跟进

补丁目的

让 active load balance(ALB)这条"异步 fallback 路径"在 CAS(cache-aware scheduling)触发的 LLC 方向迁移中只搬动 preferred LLC 与目标 LLC 匹配的任务。被动 LB 在 passive_balance() 中把 group_llc_balance 标成 migrate_llc_task,但当被动 LB 拿不走任务时排队的 ALB 由 CPU stopper 在目标 CPU 上重新构造 lb_env,迁移类型被默认成 migrate_load(值 0),导致:

  • ALB 在 can_migrate_task() 中看到任务 ppreferred_llc 与目标 LLC 不一致时仍按 migrate_load 接受,把 p 从其 preferred LLC 拉走。
  • 引入 CAS 没有预期的副作用:src_rq 上 p1 想往 dst_llc 走、p2 想留 src_llc,被动 LB 因 p1 被 pinned/cache-hot/容量约束失败时触发 ALB,cfs_tasks 倒序遍历撞上 p2,把它错误拽出 preferred LLC。

旧流程的问题

passive_balance() 算出 imbalance 后选最忙 group,置 busiest->active_balance = 1push_cpu = this_cpu,并 stop_one_cpu_nowait() 排队 ALB。问题在 active_load_balance_cpu_stop() 在 dst_cpu 上构造一份全新的 lb_envflags 只设 LBF_ACTIVE_LBmigration_type 默认 0 即 migrate_loadmigrate_llc_task 的所有判断(alb_break_llc()migrate_degrades_llc()can_migrate_task() 的 LLC 路径)都依赖 env->migration_type == migrate_llc_task;ALB 沿用默认值后,CAS 触发的 ALB 退化成了普通 load migration,丢掉了"只搬方向匹配的任务"的约束。

新流程

v2 采纳 Chen Yu 的建议:不再把 migration_type 透传到 stopper,而是在 sched_balance_rq() 排队 ALB 时根据 env->migration_type 挑选 stopper 回调:

  • migrate_llc_taskactive_load_balance_llc_cpu_stop()
  • 其它 → 原 active_load_balance_cpu_stop()

两个 stopper 都进入 __active_load_balance_cpu_stop(data, lb_flags),llc 版本把 LBF_ACTIVE_LB_LLC 加进 env->flagsmigrate_llc_task_wrong_dst() 同时识别 migration_type == migrate_llc_taskenv->flags & LBF_ACTIVE_LB_LLC。这样既避免把 migration_type 改写成非 migrate_load(防止 sched_delayed 任务被拒迁),又让 ALB 路径上的 LLC 检查仍能识别 CAS 触发的迁移方向。

关键实现

#define LBF_ACTIVE_LB_LLC 0x40

static inline bool
migrate_llc_task_wrong_dst(struct task_struct *p, struct lb_env *env)
{
    return sched_cache_enabled() &&
           (env->migration_type == migrate_llc_task ||
            env->flags & LBF_ACTIVE_LB_LLC) &&
           READ_ONCE(p->preferred_llc) != llc_id(env->dst_cpu);
}

static inline cpu_stop_fn_t alb_stop_fn(struct lb_env *env)
{
    if (env->migration_type == migrate_llc_task)
        return active_load_balance_llc_cpu_stop;
    return active_load_balance_cpu_stop;
}

static int __active_load_balance_cpu_stop(void *data, unsigned int lb_flags)
{
    /* ... 构造 lb_env,flags = LBF_ACTIVE_LB | lb_flags ... */
}

sched_balance_rq() 中用 alb_stop_fn(&env) 选择 stopper;migrate_degrades_llc()can_migrate_task() 都复用 migrate_llc_task_wrong_dst(),ALB 路径上检测到 preferred_llc 不匹配时返回 0,避免把 p2 拖出 preferred LLC。

Patch 概览

v1:新增 rq->active_balance_type 保存 migration_type;stopper 构造 lb_env 时把 active_balance_type 强转回 migration_type
v2:弃用 rq->active_balance_type;引入 LBF_ACTIVE_LB_LLCalb_stop_fn();新增 active_load_balance_llc_cpu_stop()__active_load_balance_cpu_stop(data, lb_flags);commit message 增 Suggested-by Chen, Yu C。v2 调整原因:v1 改写 env->migration_type 会触发 can_migrate_task()(p->se.sched_delayed) && env->migration_type != migrate_load 的拒迁分支,殃及 delayed-dequeue 任务。

类比

把 ALB 想成"调度员替同事代搬一箱文件":被动 LB 是发起人,他递纸条说"把这箱搬到 3 楼那间(migrate_llc_task)";但 stopper 接收时纸条被换成了"搬到 3 楼,哪间都行(migrate_load)"。v1 的修法是让发起人把原话写进搬运动线 rq->active_balance_type,stopper 重新念一遍——但这会污染原本"搬所有可搬的东西"的语义,把不想搬的同事(sched_delayed)也挡掉。v2 改成"发起人挑一个会念原话的搬运动线(active_load_balance_llc_cpu_stop)",让搬运动线自己在 lb_env 上贴一张小标签 LBF_ACTIVE_LB_LLC,原话(migration_type)仍保留 migrate_load 默认值,搬运动线在门口核对"小标签 + 目标 LLC"再决定搬不搬。

                   passive_balance()
                          |
                sets env->migration_type
                = migrate_llc_task
                          |
                          v
                 need_active_balance()
                          |
                if (group_llc_balance == CAS):
                       queue active balance
                          |
                          v
            +--------- alb_stop_fn(env) ---------+
            |                                    |
   env->migration_type               env->migration_type
   == migrate_llc_task                != migrate_llc_task
            |                                    |
            v                                    v
active_load_balance_llc_cpu_stop()  active_load_balance_cpu_stop()
            |                                    |
            v                                    v
__active_load_balance_cpu_stop(data,        __active_load_balance_cpu_stop(data,
                          LBF_ACTIVE_LB_LLC)                          0)
            |                                    |
            v                                    v
   env->flags |= LBF_ACTIVE_LB_LLC     env->flags = LBF_ACTIVE_LB
            |                                    |
            +----------------+-------------------+
                             v
                    can_migrate_task(p)
                             |
                 migrate_llc_task_wrong_dst()
                             |
       (preferred_llc != llc_id(dst_cpu)) ?
                             |
                  +----------+----------+
                  |                     |
               reject                  accept

Highlight:风险与注意点

  • 行为变更面:v1 改写 migration_type 会触发 can_migrate_task()sched_delayed 任务的拒迁分支;v2 通过 env->flags 隔离该影响,但 ALB 路径上任何对 migration_type 的隐式假设都值得再审计(例如未来新增的 ALB 检查分支)。
  • 触发概率:被动 LB 大多数情况下会先搬走 p1,真正出现"p1/p2 同时留在 src_rq 并触发 ALB"的概率较低;review 中作者与 Tim/Chen Yu 反复讨论"是否真的会出现",缺乏 trace 数据,建议加 tracepoint 或微基准验证。
  • 数据一致性:migrate_llc_task_wrong_dst() 直接读 READ_ONCE(p->preferred_llc)preferred_llcmigrate_misplaced_task() 命中后会被更新,需要确认节点/CPU 拓扑变化时是否会残留错误绑定。
  • sched_cache_enabled() 关闭时 wrong_dst 直接返回 false,patch 在未启用 CAS 的构建里是空操作,需要测试覆盖关闭路径。
  • 文档与日志:Chen Yu 建议补 [Problem Statement] 章节并把"为什么需要新增 stopper 函数"的论证写进 commit log,作者同意润色;正式合入前应落实。

版本变化

v1 → v2:放弃 rq->active_balance_type;引入 LBF_ACTIVE_LB_LLCalb_stop_fn();新增 active_load_balance_llc_cpu_stop()__active_load_balance_cpu_stop(data, lb_flags);commit message 增加 Suggested-by Chen, Yu C;v2 已获 Reviewed-by: Tim Chen。thread 末尾 Chen Yu 还提出两条 commit log 润色建议,作者同意采纳。

一句话总结

该 patch 让 active load balance 在 CAS 触发时仍只把 preferred LLC 与目标 LLC 匹配的任务拉走,避免在 fallback 异步路径上把"不想搬家的人"错误拖出 preferred LLC;v2 通过挑选 stopper 回调 + LBF_ACTIVE_LB_LLC 标志规避了改写 migration_typesched_delayed 任务的副作用。