0/2 已展开

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-ID20260819012157.220932-1-cui.tao@linux.dev
  • 完整性:完整,含 1 封维护者回复(Tejun Heo)

补丁目的

sched_ext 文档明确说明 cgroup CPU 控制器旋钮(cpu.maxcpu.weightcpu.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 小节,说明:

  1. fair class 由内核强制 cgroup 旋钮;sched_ext 仅透传给 BPF 调度器。
  2. 是否/如何生效由加载的调度器决定;未实现对应回调时旋钮被忽略。
  3. 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:风险与注意点

  1. 文档粒度争议:Tejun Heo 指出"列举哪些调度器不实现"和"特别点名 nr_throttled"
    对读者帮助有限,因为当下大多数 BPF 调度器都没实现 cpu.max;建议改得更通用。
  2. nr_throttled 计数不可见:即便调度器实现了 cpu.max,SCX 也没有把 nr_throttled
    计数路由出来(据 Tejun 提及目前只有 scx_lavd 做了),文档举 nr_throttled 作为
    例子可能误导读者以为该计数一定可见。
  3. 静默失败难调试:未实现回调时没有任何日志或警告,用户可能长期误判配额。
    未来若要彻底解决,可能仍需在 sched_ext 端加 pr_warn_once()(v1 就这么做的)。
  4. 范围不限于 cgroup:commit message 提到"nice 级别等其它旋钮也一样",文档
    已覆盖但描述较模糊;后续若引入更多可调旋钮需要重新审视。

版本变化

  • v1 → v2
    • 删除 v1 中 pr_warn_once() 提示"未实现 ops.cgroup_set_bandwidth()"的代码改动;
    • 改为在 sched-ext.rst 的 Basics 段新增 Scheduler-Dependent Knobs 小节做文档说明;
    • 改动遵循 RFC 阶段的 review 建议,避免运行时警告噪声。

一句话总结

v2 把"cgroup CPU 旋钮是否生效取决于 BPF 调度器实现"这条契约写进 sched-ext 文档,
但 Tejun 指出文档对 nr_throttled 的细节引用和调度器实现列举过于具体,建议再精简。