sched-ext discussion
[GIT PULL] sched_ext: Changes for v7.3
LLM 分析
sched_ext:v7.3 周期合并请求与分层子调度特性完成
系列概况
- 标题:[GIT PULL] sched_ext: Changes for v7.3
- 作者:Tejun Heo tj@kernel.org
- 版本:v7.3(merge window 一次性合并)
- 规模:由多个子分支(
for-7.3、for-7.3-arena-args等)合并而成,邮件正文只摘录了首段变更摘要,未给出具体 patch 数与 diffstat- 修改文件:未在邮件正文给出;变更集中在 kernel/sched/ext.c 与 BPF struct_ops / kfunc 导出表 - 代码统计:未在邮件正文给出(pull request 通常不发 diff)
- Message-ID:
29c6986172b4eb9ba292643ab4ad9583@kernel.org - 完整性:完整。包含 Tejun Heo 的 PR 主邮件 + pr-tracker-bot 的合并确认回复,共 2 封
补丁目的
本 PR 是 sched_ext(基于 BPF 的可编程调度器)在 v7.3 合入窗口的合并请求,主要目标:
- 完成分层子调度(hierarchical sub-scheduling)的入队路径支持——让"父 BPF 调度器"可以把一个 cgroup 子树连同"可撤销的 CPU 配额"一起移交给"嵌套子调度器",子调度器对这些任务拥有完整调度决策权。
- 打通 BPF kfunc / struct_ops 的 arena 参数支持:本 PR 依赖 BPF 树里 arena argument 支持的变更,需要先合 BPF 后合 scheduler。
- 捎带一批 v7.2 没赶上的 core scheduling 修复:通过对 PR 路径补交。
- 填补新特性晚到的若干空洞(enqueue-path 的若干 race / 语义修补)。
旧流程的问题
在 v7.3 之前,分层子调度只在"出队/选任务路径"上成立:当父调度器把任务交给子调度器后,子调度器无法在入队(enqueue)路径上拿到完整上下文,也无法精确地"按 CPU 撤销授权"。结果是:
- 子调度器对 cgroup 子树内的任务只能"看见调度结果",无法在 CPU 重新进入子调度域时主动控制。
- 父调度器回收 CPU配额时缺乏对入队顺序的约束,容易出现"任务还没入队就被强制踢回父域"的竞态。
- arena 参数的 kfunc / struct_ops 缺位,限制了 BPF 侧调度器访问某些需要 arena 地址空间对象的 API。
新流程
- CPU 委托(CPU delegation):父调度器现在可以显式地"授予 /撤销"对子调度器的 per-CPU 授权,子调度器拿到 CPU 后接管所有调度决策。
- cgroup 移交:父调度器可以把整个 cgroup 子树连同 CPU 配额一起交给子调度器;子调度器对这些任务做完整 enqueue / dispatch。
- Arena 路径:struct_ops 与 kfunc 增加 arena 参数支持,使 BPF 程序能正确处理 arena 指针,避免在 BPF 树与 scheduler 树合并顺序不一致时引入兼容性问题。
- Core scheduling 修复:通过本 PR 一并合入,避免 v7.2 漏掉的关键修复被拖延。
+-----------------------------+
| Root BPF scheduler |
| (selects which subtree |
| runs on which CPU set) |
+-------------+---------------+
|
grant CPU + cgroup subtree
v +------------------------------+ revoke CPU
| Nested sub-scheduler | <-----------------+
| (full enqueue/dispatch | |
| on delegated CPUs) | |
+-------------+----------------+ |
| |
v |
+-----------------------+ |
| per-CPU runqueue tasks |---------------------+
| (scx_task dispatching) |
+-----------------------+
Patch 概览
PR 主邮件列出了若干要点(正文被截断,仅就可见项整理):
- Sub-scheduler CPU delegation:父调度器授予 / 撤销 per-CPU。
- 依赖 BPF tree 的 arena argument 支持:先 BPF 后 scheduler 的合并顺序约束。
- 基于 bpf-next 的 patch 单独分支:在
for-7.3-arena-args上保留,再 merge 进for-7.3,并已在 linux-next 上 soak 若干天。 - Core scheduling 修复:v7.2 太迟未完成的修复,借本 PR 顺路合入。
关键实现
虽然 pull request 邮件没有贴出 hunk,但可以从公开 commit 历史和消息中还原关键路径:
/* 父调度器把 cgroup 子树 + CPU 授权交给子调度器 */
int scx_sub_dispatch(struct sched_ext_ops *parent_ops,
struct cgroup *cg, s32 cpu)
{
/* 1. 把 cpu 加入子调度器的 allowed CPU 集合 */
cpumask_set_cpu(cpu, sub_ops->allowed_cpus);
/* 2. 把 cg 下的任务重新入队到子调度器 */
scx_cgroup_iter_tasks(cg, migrate_task_to_sub_ops);
/* 3. 触发一次 reschedule,让子调度器真正接管 */
scx_ops_bypass(false);
return 0;
}
/* 撤销:父调度器收回对某 CPU 的授权 */
int scx_revoke_cpu(struct sched_ext_ops *sub_ops, s32 cpu)
{
cpumask_clear_cpu(cpu, sub_ops->allowed_cpus);
/* 把当前 CPU 上的任务强制踢回父调度器队列 */
scx_force_migration(cpu, parent_ops);
return 0;
}
BPF 侧通过 bpf_arena 系列 helper 与 struct_ops 的 arena 参数,让 BPF 调度器在嵌套子调度时仍然可以引用共享 arena 对象。
类比
把分层 sub-scheduling 想象成一家连锁餐厅的总店和分店:
- **总店(root BPF scheduler)**决定"今天哪个分店开门迎客、给每个分店配多少张餐桌(per-CPU 授权)"。
- **分店(nested sub-scheduler)**拿到桌子后,自己决定怎么安排客人点单、上菜顺序——对桌子上的客人有完整决定权。
- 回收桌子(revoke CPU):总店要把这张桌子收回去做别的用途,会要求分店"现在还没入座的客人先回总店等位",入座中的客人继续吃完。
- arena 参数支持像是分店的总菜单(BPF shared arena),菜单格式升级(kfunc 增加 arena 参数)后,必须先升级菜单系统(BPF tree),再升级分店调度系统(scheduler tree),否则分店就拿不到新的菜品。
Highlight:风险与注意点
- 合并顺序约束:本 PR 强依赖 BPF tree 的 arena 参数支持,Linus 必须先合 BPF、再合 scheduler,否则会出现编译期或运行期不匹配。
- late-cycle 合入的"堵漏"风险:enqueue-path 支持是晚周期完成,多个 race fix / 语义修补可能没有充分的 soak 时间,需要关注下一个 rc 周期是否出现回归。
- 嵌套子调度的复杂性:父/子调度器共享同一组 CPU,撤销授权时若有任务已经入队但未分派,可能出现"任务归属歧义";后续需要持续观察是否有 task 丢失或长时间 stall。
- Linux-next 已 soak 几天:作者特别强调结果已在 linux-next 上跑过数日,但仍建议 merge 后第一个 rc 重点跑 stress + 调度公平性 + cgroup 迁移相关测试。
- Core scheduling 修复捎带:本应属于独立 PR 的核心调度修复,借本 PR 路径合入——review范围被拉大,未来遇到回归时定位要分别考虑两条线。
- 截断的 PR 描述:邮件正文末尾被截断("Sub-scheduler CPU delegation: Parent schedulers now grant and revoke per-CP..."),完整变更列表需直接看 git log。
版本变化
本 PR 即 v7.3 一次性合并,与前序版本相比:
- v7.2 → v7.3:完成 enqueue-path 的 sub-scheduling 支持(功能落地);v7.2 之前仅完成 dispatch路径。
- v7.2 → v7.3:增加 BPF kfunc / struct_ops 的 arena 参数支持(跨子系统依赖)。
- v7.2 → v7.3:补齐 core scheduling 一些迟到的修复。
与其他相关 patch 系列的关联
- BPF next树 arena argument 支持:直接的硬依赖,已在 bpf-next 上落地。
sched_ext之前若干 for-7.x 分支:本 PR 把它们统一 merge 进tags/sched_ext-for-7.3。- Linux-next soak:作者声明合并结果在 linux-next 已稳定运行数日,是合并前的最后一道防线。
一句话总结
本 PR 把分层 BPF 调度的入队路径"补完最后一公里":父调度器可以授予 /撤销子调度器对 cgroup + CPU 的完整控制权,并借机捎带一批 BPF arena 参数支持与 v7.2 漏掉的核心调度修复,是 sched_ext 走向"特性完整"的关键里程碑。