0/5 已展开

LLM 分析

sched_ext:在 scx_cgroup_init_args 中传递初始 cpu.idle 状态

系列概况

  • 标题:[PATCH v2] sched_ext: pass the initial cpu.idle state in scx_cgroup_init_args
  • 作者:Tao Cui cuitao@kylinos.cn
  • 版本:v2(线程内预告 v3 重命名字段)
  • 规模:单 patch,3 个文件,+8/-1
  • 修改文件:kernel/sched/ext/ext.ckernel/sched/ext/internal.hkernel/sched/ext/sub.c
  • 代码统计:3 文件,8 处新增,1 处删除(v1 自述,v2 diff 与之接近)
  • Message-ID(首封):20260824142817.568085-1-cui.tao@linux.dev
  • 完整性:单 patch + 3 封回复(Andrea Righi、Tejun Heo、Tao 两次回应),v3 未在本线程展开。

补丁目的

scx_cgroup_init_args 把 cgroup 的初始 weight 与带宽控制参数传给 BPF 调度器的 ops.cgroup_init(),但漏掉了 cpu.idle 标记。结果是:调度器加载时已处于 idle 的 cgroup 在 init 阶段被当作非 idle,BPF 调度器只有等到用户再次写 cpu.idle 时才会经由 ops.cgroup_set_idle() 收到通知,造成「初始状态丢失」。

旧流程的问题

   user writes cpu.idle=1           sched_ext is loaded
            |                              |
            v                              v
  cgroup fs marks idle         walk already-existing cgroups
            |                              |
            |                              v
            |                  scx_cgroup_init() fills weight/bw_*
            |                              |
            |                              v
            |                  ops.cgroup_init() sees idle=0 (WRONG)
            |                              |
            v                              |
   ops.cgroup_set_idle() callback only on next write
            |                              |
            v                              v
 finally known                  initial state lost

cpu.idle 的初值被忽略,调度器只能被动等下一次写入。

新流程

   any place that builds scx_cgroup_init_args
                    |
   +----------------+----------------+
   |                |                |
   v                v                v
scx_tg_online  scx_cgroup_init   sub.c: claim / return
   |                |                |
   +--------+-------+--------+
            |                |
            v                v
   args.idle = tg->scx.idle  (v3 -> sched_idle)
            |
            v
   ops.cgroup_init() sees initial idle (CORRECT)

struct scx_cgroup_init_args 新增 bool idle(v3 改名 sched_idle),四处构造位置统一填上 tg->scx.idle

Patch 概览

v1 漏了 sub-scheduler 交接路径(Andrea Righi 与 sashiko AI review bot 指出);v2 在 sub.cscx_cgroup_claim_subtree()scx_cgroup_return_subtree() 补齐:

/* kernel/sched/ext/internal.h */
struct scx_cgroup_init_args {
    u64 weight;
    u64 bw_period_us;
    u64 bw_quota_us;
    u64 bw_burst_us;
    /* whether the cgroup is configured idle via cpu.idle */
    bool idle;          /* v3: -> sched_idle */
};

四个填充点都加一行 .idle = tg->scx.idle,

关键实现

/* scx_tg_online(): cgroup 在调度器之后上线 */
static int scx_tg_online(struct task_group *tg)
{
    struct scx_cgroup_init_args args = {
        .weight       = tg->scx.weight,
        .bw_period_us = tg->scx.bw_period_us,
        .bw_quota_us  = tg->scx.bw_quota_us,
        .bw_burst_us  = tg->scx.bw_burst_us,
        .idle         = tg->scx.idle,    /* new */
    };
    ...
}

/* scx_cgroup_init(): cgroup 已存在,调度器加载 */
.idle = tg->scx.idle,                    /* new */

/* sub.c: 子调度器交接 */
.idle = tg->scx.idle,                    /* new in v2 */
.idle = tg->scx.idle,                    /* new in v2 */

验证:作者用 probe BPF 调度器在 VM 中打印 init args,确认「加载前 cpu.idle=1 的 cgroup 在 ops.cgroup_init() 中看到 idle=1、默认看到 0、后续 cpu.idle 写入仍走 ops.cgroup_set_idle()」。sub-scheduler 路径只做了编译验证。

类比

cgroup_init_args 想成「新生婴儿登记表」:宝宝出生(cgroup 创建或被 sched_ext 接管)就要把当时的体重、血型记上去。旧流程漏了「是否标记为『安静型宝宝』」这一栏,托儿所(BPF 调度器)只能默认所有婴儿都活泼,等家长下次再强调一遍才知道。补丁补上这一栏;同时 Tejun 建议把字段从 idle 改成 sched_idle,避免和「CPU 是否闲着」(CPU idle)混淆——就像把登记表的「安静型」明确写成「安静型(SCHED_IDLE)」,避免保育员把它误解成「宝宝在睡觉」。

Highlight:风险与注意点

  • 命名歧义:Tejun 指出 sched_ext 中裸 idle 一律指 CPU idle(ops.update_idle()、idle cpumasks、scx_bpf_pick_idle_cpu()),args.idle 会让 BPF 作者误读;v3 必须改为 sched_idle,建议同步重命名 tg->scx.idle
  • API 兼容性:scx_cgroup_init_args 是 BPF 调度器通过 vmlinux.h 看到的公开 ABI,字段重命名是一次破坏性变更,需在 release notes 中同步强调。
  • Fixes tag:Andrea 建议补 Fixes: 347ed2d566da ("sched/ext: Implement cgroup_set_idle() callback"),补上后才能进 stable。
  • Patch 拆分:作者计划把「新增字段」与「tg->scx.idle 重命名」拆成 1/2 与 2/2,前者保持最小、便于 stable backport。
  • 验证深度:sub-scheduler 两条路径只跑了编译,未来若新增构造 args 的位置(如某条 hotplug 路径),需保持同步。
  • AI 评审信号:sashiko AI review bot 协助发现 v1 漏掉的 sub.c 两处,说明 AI 评审正在进入内核 review 流程,值得后续观察其准确率与误报率。

版本变化

  • v1 → v2:补齐 sub.cscx_cgroup_claim_subtree()scx_cgroup_return_subtree() 两处 .idle(Andrea Righi 与 sashiko AI 指出)。
  • v2 → v3(作者预告,未在本线程展开):
    • scx_cgroup_init_args.idlesched_idle
    • tg->scx.idletg->scx.sched_idle(独立第二 patch);
    • Fixes: tag;
    • Andrea Righi 给 Reviewed-by

一句话总结

补丁修复 sched_ext 在 init 阶段丢失 cgroup cpu.idle 状态的问题,统一在四处构造 scx_cgroup_init_args 的路径补齐该字段,v3 按 Tejun 建议改名为 sched_idle 以消除与 CPU idle 的歧义。