sched-ext discussion
[PATCH sched_ext/for-7.2-fixes] sched_ext: mark waker CPU busy when selected in WAKE_SYNC case
LLM 分析
sched_ext: WAKE_SYNC 场景下标记唤醒者 CPU 为 busy
系列基线信息
| 字段 | 值 |
|---|---|
| 标题 | sched_ext: mark waker CPU busy when selected in WAKE_SYNC case |
| 作者 | Kuba Piecuch (Google) |
| 目标分支 | sched_ext/for-7.2-fixes |
| 规模 | 1 file, +3 / −1 |
| Message-ID | 20260722143307.2772632-1-jpiecuch@google.com |
| 来源 | sched-ext 频道 |
| 状态 | 已被 Tejun Heo 合入 for-7.2-fixes |
明确目的
SCX 的内置 idle CPU 追踪与实际 idle 状态可能不一致——尤其刚启用 SCX 时,
scx_idle_enable() 会把所有 online CPU 一股脑标记为 idle。
在 SCX_WAKE_SYNC 路径中,scx_select_cpu_dfl() 若选定了唤醒者(waker)CPU,
则跳过了将该 CPU 标记为 busy 的步骤。于是 waker CPU 在被选中之后仍然挂着 idle 标签,
wakee 切过来也跑在"看起来 idle"的 CPU 上。
allowed_cpus selftest 因此失败,dmesg 报:
allowed_cpus.bpf.c:21: CPU 0 should be marked as busy
本 patch 在 WAKE_SYNC 选中 waker CPU 时显式调用 scx_idle_test_and_clear_cpu(cpu),
将其从 idle mask 中摘除,修复该问题。
遍历代码
补丁只改了一个文件 kernel/sched/ext/idle.c,核心改动约 2 行:
if (cpumask_test_cpu(cpu, allowed)) {
scx_idle_test_and_clear_cpu(cpu); // <-- 新增:清除 idle 标记
}
改动位置:scx_select_cpu_dfl() 函数,处理 SCX_WAKE_SYNC 选中 waker CPU 的分支。
逻辑流程:
-
scx_select_cpu_dfl()在WAKE_SYNC场景下优先考虑 waker CPU,
因为 wakee 与 waker 有同步关系,共享 cache 更有利。 -
选中 waker CPU 后,原代码只做了
cpumask_test_cpu(cpu, allowed)检查,
然后直接跳到out_unlock返回——没有像其他路径那样调用
scx_idle_test_and_clear_cpu()把选中 CPU 从 idle mask 移除。 -
补丁在此处补上
scx_idle_test_and_clear_cpu(cpu),确保 waker CPU
一旦被选中,就不再被 idle 追踪视为空闲。 -
返回后,调度器继续将 wakee 放到该 CPU 执行,idle 状态已正确反映为 busy。
ASCII 流程图
scx_select_cpu_dfl()
|
wake_flags & SCX_WAKE_SYNC ?
/ \
YES NO
| |
waker CPU 可用 ? 常规 CPU 选择路径
(allowed mask) → scx_idle_test_and_clear_cpu()
| | (已存在)
┌─ 之前 ─┐ ┌─ 补丁后 ─┐
│ 直接返回 │ │ test_and_clear │
│ waker CPU│ │ waker CPU idle │
│ 仍标 idle│ │ 标记 → busy │
└──────────┘ └────────────────┘
| |
idle mask 不一致 idle mask 一致 ✓
→ selftest 失败 → selftest 通过 ✓
概念类比
想象一个停车场管理系统:
-
入口闸机(
scx_idle_enable())刚上线时,把所有车位统一标记为"空",
哪怕有些车位上还停着车——这就是 idle 追踪初始化的不准确。 -
当一个司机(waker)在自己车位上接了一位新乘客(wakee),
停车系统本应把该车位标记为"已占用",但因为同步场景的特殊逻辑,
系统认为"司机本来就在这儿,不需要重新标记"——车位仍显示"空"。 -
补丁就是:即使司机没挪位置,也要重新刷一次车位状态,
确保系统知道这个车位正在被使用。
Highlight 窗出问题
-
仍存在不可修复的竞态:作者承认
pick_task_idle()可在 CPU 选择与验证之间
再次把选中 CPU 标回 idle——极小概率但理论上存在,且"难以修复"。
未来如果 selftest 仍偶发失败,需判断是否属于此竞态。 -
初始化阶段 idle mask 全量标记的固有偏差:
scx_idle_enable()把所有 online CPU
一股脑标 idle,是根因之一。本补丁只修了 WAKE_SYNC 一个路径;
是否还有其他路径也存在类似"选中但没清 idle"的遗漏,值得后续排查。 -
只影响 sched_ext:此问题不涉及 CFS/classic scheduler,只在 SCX BPF scheduler
的 idle 追踪中出现;测试和验证应限定在 SCX 场景。
版本演进
单版补丁,无 v1→v2 演进记录。
与其他相关 patch 系列的关联
allowed_cpusselftest:此补丁直接修复了该 selftest 的失败;
该测试专门验证 SCX idle tracking 与实际 CPU 状态的一致性。scx_idle_enable()初始化逻辑:补丁 commit message 明确指出初始化全量标记 idle
是偏差来源之一,后续可能有针对初始化阶段的改进。
一句话总结
补丁在 scx_select_cpu_dfl() 的 WAKE_SYNC 分支补上 scx_idle_test_and_clear_cpu(),
修复 waker CPU 被选中后仍标记 idle 的问题,已被 maintainer 合入 for-7.2-fixes。