sched-ext discussion
[PATCH] sched_ext: pass the initial cpu.idle state in scx_cgroup_init_args
LLM 分析
sched_ext:将初始 cpu.idle 状态传入 scx_cgroup_init_args
系列概况
- 标题:[PATCH] sched_ext: pass the initial cpu.idle state in scx_cgroup_init_args
- 作者:Tao Cui cuitao@kylinos.cn
- 版本:v1(单 patch,未见 [vN] 前缀)
- 规模:1 个 patch
- 修改文件:
kernel/sched/ext/ext.c、kernel/sched/ext/internal.h - 代码统计:2 files changed, 6 insertions(+), 1 deletion(-)
- Message-ID:20260824133954.561956-1-cui.tao@linux.dev
- 完整性:完整。包含 commit message、diff、Signed-off-by 与 author 署名;message 3、4 因原文抓取截断,仅保留 partial body
补丁目的
sched_ext 在 cgroup 初始化时,会把 cgroup 当前的 weight、带宽控制等初始参数打包进 struct scx_cgroup_init_args,通过 ops.cgroup_init() 一次性交给 BPF scheduler。但这个结构体目前缺少 cpu.idle 字段,导致:
- 在 sched_ext 加载之前就已经被标记为 idle 的 cgroup,BPF scheduler 看到的是
idle=0; - 用户必须再次向
cpu.idle写入相同值,触发ops.cgroup_set_idle(),BPF 侧才"后知后觉"。
本 patch 的目标就是补齐 cpu.idle 在 cgroup_init 阶段的初始状态,让 BPF scheduler 在挂载时就能拿到正确的 idle 标记。
旧流程的问题
user writes cgroup cpu.idle=1
|
v
cgroup_file -> cgroup_idle_write()
|
v
tg->scx.idle = 1 (saved internally)
|
v
ops.cgroup_set_idle() notifies BPF scheduler
|
v
BPF knows "this cgroup is idle"
but if sched_ext was loaded AFTER cpu.idle=1 was written:
|
v
tg->scx.idle = 1 (already true)
scx_cgroup_init_args has no idle field
|
v
ops.cgroup_init() receives weight/bw but no idle flag
|
v
BPF scheduler wrongly assumes idle=0,
until the user rewrites cpu.idle by hand
新流程
sched_ext load / scx_tg_online
|
v
build scx_cgroup_init_args {
.weight,
.bw_period_us,
.bw_quota_us,
.bw_burst_us,
.idle = tg->scx.idle # newly added
}
|
v
SCX_CALL_OP_RET(ops.cgroup_init, ...)
|
v
BPF scheduler sees the real idle state
at attach time, no extra writes needed
Patch 概览
- 在
struct scx_cgroup_init_args增加bool idle字段,并附注释说明语义; - 在
scx_tg_online()(scheduler 已加载后上线的 cgroup)和scx_cgroup_init()(scheduler 加载时已存在的 cgroup)两个构造点都填入tg->scx.idle。
关键实现
/* 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; /* newly added */
};
/* kernel/sched/ext/ext.c, scx_tg_online() */
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, /* newly added */
};
/* kernel/sched/ext/ext.c, scx_cgroup_init() */
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, /* newly added */
};
两处构造点对称:一个处理"加载之后才出现的 cgroup",另一个处理"加载时已存在的 cgroup"。两条路径都把 tg->scx.idle 这个早已存在的内部状态原样透出,没有引入新的数据来源。
类比
把 sched_ext 想象成一家新上任的物业公司,要接管一栋已经有租户(cgroup)的写字楼。
物业公司搬进来时,手里有一份"住户登记表",上面写了每户的房租、面积、带宽配额——但漏掉了"哪些房间目前空置"这一栏。于是物业默认所有房间都是满租,直到住户主动再来前台补登一次。
这个 patch 就是给登记表补上"是否空置"那一栏。物业公司一接手,就能立刻掌握每户的占用情况,不需要住户再跑一趟重复登记。
Highlight:风险与注意点
- sub-scheduler 初始化路径遗漏:sashiko-bot 指出,
kernel/sched/ext/sub.c中scx_cgroup_claim_subtree()与scx_cgroup_return_subtree()也构造了scx_cgroup_init_args,但本 patch 没有同步更新这两处,.idle隐式为 false,idle 状态仍可能丢失。这是中等级别的风险,需要在 v2 中一并修复。 - 设计上的小争议:sched_ext 体系一直强调通过
cgroup_set_idle()这类"事件型"回调把状态变化告知 BPF,让 BPF 自行维护一份镜像。本次 patch 选择在cgroup_init()一次性传入,是否暗示"挂载即镜像"是更被期待的语义?后续可以关注 maintainer(Andrea Righi 等)是否倾向统一到事件驱动、抑或在 init 路径透出更多字段。 - 一致性注意:
ops.cgroup_init()的语义是新挂载时调用,因此参数应被理解为"挂载时刻的快照",不应被 BPF 用作"当前真实状态"缓存;BPF scheduler 仍需以cgroup_set_idle()的事件流为准更新其内部状态。 - 回复截断:lore 上的 message 3(Andrea Righi)和 message 4(Tao Cui 回复)正文未完整抓取,需要跟踪后续版本以了解 maintainer 的明确表态。
版本变化
只有 v1,暂无 v2。预期 v2 需要补 kernel/sched/ext/sub.c 中 sub-scheduler 路径的 .idle 初始化。
一句话总结
这个小 patch 把 cgroup 的 cpu.idle 初始状态补进 scx_cgroup_init_args,修掉了"已 idle 的 cgroup 在 sched_ext 挂载时呈现为非 idle"的语义漏洞,但仍需补齐 sub-scheduler 路径并等待 maintainer 进一步表态。