sched-ext discussion
[PATCH v2] docs/sched_ext: document that cgroup CPU knobs are scheduler-dependent
LLM 分析
sched_ext:cgroup CPU 旋钮是调度器相关的
系列概况
- 标题:[PATCH v2] docs/sched_ext: document that cgroup CPU knobs are scheduler-dependent
- 作者:Tao Cui cuitao@kylinos.cn
- 版本:v2(RFC → v2)
- 规模:1 个文件,18 行新增
- 修改文件:
Documentation/scheduler/sched-ext.rst - 代码统计:18 insertions(+), 0 deletions(-)
- Message-ID:20260819012157.220932-1-cui.tao@linux.dev
- 完整性:完整,含 1 封维护者回复(Tejun Heo)
补丁目的
sched_ext 文档明确说明 cgroup CPU 控制器旋钮(cpu.max、cpu.weight、cpu.idle)在
sched_ext 下的"行为契约"——sched_ext 只是把旋钮透传给 BPF 调度器,是否生效取决于
加载的调度器是否实现对应的 ops.cgroup_set_*() 回调。这避免用户/编排器误以为
在 fair class 下"自动 throttle"的行为在 BPF 调度器下也成立。
旧流程的问题
在 fair class 中,cpu.max 等旋钮由内核直接强制:超过配额就会限流,nr_throttled
计数会增加。但 sched_ext 把 cgroup 旋钮"外包"给 BPF 调度器:
- 用户写
cpu.max=50000→ sched_ext 调用ops.cgroup_set_bandwidth()→ - 如果 BPF 调度器没有实现这个回调 → 静默忽略,cgroup 满速运行。
这种"静默失败"会让用户和容器编排器以为配额生效,掩盖调度器实现的差异。
新流程
在 sched-ext.rst 新增 Scheduler-Dependent Knobs 小节,说明:
- fair class 由内核强制 cgroup 旋钮;sched_ext 仅透传给 BPF 调度器。
- 是否/如何生效由加载的调度器决定;未实现对应回调时旋钮被忽略。
- nice 级别等其它旋钮同样遵循"由调度器决定"规则。
并用 scx_simple / scx_flatcg / scx_central 未实现 cgroup_set_bandwidth() 作为例子。
Patch 概览
- 文件:
Documentation/scheduler/sched-ext.rst - 插入位置:Basics 段附近,在 Dispatch Queues 之前
- 新增小节:
Scheduler-Dependent Knobs
关键实现
补丁纯文档,无代码改动。要点是一段 RST 段落:
Scheduler-Dependent Knobs
-------------------------
The fair class enforces cpu controller knobs such as cpu.max,
cpu.weight and cpu.idle in the kernel. sched_ext only passes them
to the BPF scheduler through ops.cgroup_set_*() callbacks. Whether
and how a knob takes effect is up to the loaded scheduler: if it
doesn't implement the corresponding callback, the knob is ignored.
类比
把它想成酒店前台:你(cgroup 用户)把"请 14:00 前不要吵醒客人"的便条交给前台,
前台只负责把便条转交给客房服务员(BPF 调度器)。如果这家酒店没有客房服务员,
前台不会报错,便条静静躺在大堂里——你仍以为客房已收到指令。
scx_simple 之类的调度器就好比"没有客房服务员"的小旅馆,便条丢了也没人告诉你。
ASCII 流程图
+-----------------------+ +-------------------------+
| cgroup 文件写入 | ----> | sched_ext 内核层 |
| cpu.max / cpu.weight | | 解析旋钮、定位 cgroup |
+-----------------------+ +-----------+-------------+
|
调度 ops.cgroup_set_*() 回调
|
v
+-----------------------------+
| 加载的 BPF 调度器 |
| (scx_simple / scx_lavd / |
| scx_flatcg / 用户 BPF ...) |
+-------------+---------------+
|
实现回调? 未实现?
| |
v v
真正生效 静默忽略
(cgroup 满速跑)
常见 BPF 调度器对 cpu.max 的支持情况(v2 文末时点)
scx_simple : 未实现 cgroup_set_bandwidth() -> cpu.max 无效
scx_flatcg : 未实现 cgroup_set_bandwidth() -> cpu.max 无效
scx_central : 未实现 cgroup_set_bandwidth() -> cpu.max 无效
scx_lavd : 已实现 -> cpu.max 生效(AFAIK)
Highlight:风险与注意点
- 文档粒度争议:Tejun Heo 指出"列举哪些调度器不实现"和"特别点名 nr_throttled"
对读者帮助有限,因为当下大多数 BPF 调度器都没实现 cpu.max;建议改得更通用。 - nr_throttled 计数不可见:即便调度器实现了 cpu.max,SCX 也没有把 nr_throttled
计数路由出来(据 Tejun 提及目前只有 scx_lavd 做了),文档举 nr_throttled 作为
例子可能误导读者以为该计数一定可见。 - 静默失败难调试:未实现回调时没有任何日志或警告,用户可能长期误判配额。
未来若要彻底解决,可能仍需在 sched_ext 端加pr_warn_once()(v1 就这么做的)。 - 范围不限于 cgroup:commit message 提到"nice 级别等其它旋钮也一样",文档
已覆盖但描述较模糊;后续若引入更多可调旋钮需要重新审视。
版本变化
- v1 → v2:
- 删除 v1 中
pr_warn_once()提示"未实现 ops.cgroup_set_bandwidth()"的代码改动; - 改为在
sched-ext.rst的 Basics 段新增Scheduler-Dependent Knobs小节做文档说明; - 改动遵循 RFC 阶段的 review 建议,避免运行时警告噪声。
- 删除 v1 中
一句话总结
v2 把"cgroup CPU 旋钮是否生效取决于 BPF 调度器实现"这条契约写进 sched-ext 文档,
但 Tejun 指出文档对 nr_throttled 的细节引用和调度器实现列举过于具体,建议再精简。