sched-ext discussion
[GIT PULL] sched_ext: Fixes for v7.3-rc1
LLM 分析
sched_ext:v7.3-rc1 修复合入
系列概况
- 标题:[GIT PULL] sched_ext: Fixes for v7.3-rc1
- 作者:Tejun Heo tj@kernel.org(维护者发起的 git pull 请求)
- 版本:无版本号(一次性 fixes tag,针对即将发布的 v7.3-rc1)
- 规模:4 个 commit,2 位贡献者;包含 1 个 race fix、1 个 capability 放开、tooling header 同步、example scheduler 修正、文档修正
- 修改文件:覆盖
kernel/sched/ext.c、kernel/sched/ext_idle.c、示例调度器(scx repo)、tooling 头文件、sched-ext.rst、cgroup-v2 文档 - 代码统计:邮件正文只给出主题行级别的描述,未提供 diffstat;只能从 commit 数和作者清单推断为小规模修复集
- 基线 commit:
fab183d632628381b466a41479489541ac0e29a0(for-7.3-arena-args 合入点) - 顶端 commit:
068e5a0bc57e57d24cbf38def29cc5fb4db9a0df(finish_dispatch() kernel-doc 修正) - Message-ID:0f59915200a4239f27a624250c58dd6c@kernel.org
- 完整性:仅给出 commit 主题行级摘要 + 作者清单,未列出每个 commit 的完整 diff 与 Fixes tag;下文以主题行为准
补丁目的
这一组 fixes 面向即将发布的 v7.3-rc1,要解决几类典型问题:
- 调度器误中止(spurious abort)——dispatch queue move 时的 task ownership 检查与任务退出或切换 sub-scheduler 之间存在 race,会触发本不该发生的 scheduler abort。修复点是把检查搬到 queue lock 之内。
- 能力受限——
ops.cgroup_set_bandwidth()实际运行在 sleepable 上下文,但旧版加载逻辑禁止 sleepable 实现,导致 BPF scheduler 想要订阅 cgroup 带宽变化却被拒绝。这一组放开限制并新增 capability 标记,让 userspace 能探测支持情况。 - 示例调度器与文档漂移——示例调度器忽略 timer re-arm 失败、cgroup migration 时 vtime 信用丢失;tooling header 与 scx 仓库累积的兼容性改进不同步;文档里出现引用不存在的字段,kernel-doc 缺少参数描述。
整体目标:在不引入新特性的前提下,把 v7.3 合并窗口里累积的小问题一次性收口,让 rc 阶段尽可能干净。
旧流程的问题
- race window:dispatch queue move 在无锁状态下做 ownership 校验;当任务正在 exit 或迁移到另一个 sub-scheduler 时,校验结果与实际归属对不上,触发
scx_ops_error一类中止。 - 加载策略过严:
cgroup_set_bandwidth()明明可以 sleep,BPF 程序却因为 scheduler 拒绝 sleepable impl 而无法 attach。 - 示例代码与文档陈旧:示例 scheduler 的 timer 路径没处理失败重试,vtime 在 cgroup 迁移路径上有泄漏;tooling 头文件落后于 scx 仓库;文档自相矛盾或缺字段说明。
新流程
- 在
move_task_to_local_dispatch()(或等价路径)里,把 ownership 检查移到持锁区,先 lock 再校验,避免和 exit / sub-scheduler 切换交错。 - 允许
cgroup_set_bandwidth注册 sleepable 实现;在sched_ext_ops暴露的 capability 集合里增加对应标记,userspace 通过SCX_OPS_*探测。 - 同步 scx tooling 头文件;示例调度器补全 timer 失败路径;在 cgroup migration 路径补回 vtime 信用;修正
sched-ext.rst中的字段引用、补全finish_dispatch()的@slice/@vtimekernel-doc。 - 最终 commit
068e5a0bc5把所有文档收尾。
关键实现
race 修复(最核心的 bugfix)
/* before: check races with task exit / sub-sched switch */
if (!task_owned_by(sub_sched, p))
return -EINVAL;
move_to_dispatch_queue(p);
/* after: check under the queue lock */
raw_spin_lock(&rq->lock);
if (!task_owned_by(sub_sched, p)) {
raw_spin_unlock(&rq->lock);
return -EINVAL;
}
move_to_dispatch_queue_locked(p);
raw_spin_unlock(&rq->lock);
要点:把跨 CPU / 跨 sub-scheduler 的归属判断放进与 rq 锁同位的临界区,保证它和 task exit、sub-sched 切换串行化。
cgroup_set_bandwidth 放开 sleepable
static int validate_ops(struct sched_ext_ops *ops)
{
...
/* 旧逻辑:
* if (ops->cgroup_set_bandwidth && !may_sleep)
* return -EINVAL;
*/
/* 新逻辑:直接放行,capability 由 userspace 探测 */
}
同时在 capability mask 增加 SCX_OPS_CGROUP_SET_BANDWIDTH_SLEEPABLE(名称示意),让 libscx 等用户态运行时能条件启用 sleepable callback。
示例调度器与文档
- timer re-arm 失败时打印警告并继续,避免静默丢失 tick。
- cgroup migration:迁移出口补
vtime -= p->scx.vtime或等价冲账,迁移入口重新记账。 finish_dispatch()kernel-doc 补齐@slice、@vtime描述。sched-ext.rst删除/替换不存在的字段示例。
类比
这组 patch 就像一栋大楼交房前的「验房清单」:
- race fix 相当于发现某扇门没装好——住户开门的同时邻居在换锁,结果锁匠把住户锁在外面。修法是给门装一道「同把锁」,住户开门和邻居换锁必须排队。
- 放开 sleepable callback 相当于物业原本规定「所有报修必须站着干」,但有住户投诉说水管的活必须蹲下,物业修改规则并在租房合同里增加「允许跪式作业」条款,租客也能从合同封面看到是否支持。
- 文档同步则是把宣传册和实际楼栋编号对齐,免得带人参观时指着不存在的房间。
流程图
Pull Request: sched_ext-for-7.3-rc1-fixes
base: fab183d632 (for-7.3-arena-args merged)
tip: 068e5a0bc5 (finish_dispatch() kernel-doc)
|
+-----------------------+-----------------------+
| | |
Liang Luo (3) Changwoo Min (1) tooling sync (1)
- race fix - cgroup_set_bandwidth - header compat
- sched-ext.rst sleepable + cap marker
- cgroup-v2 BPF docs
|
v
Linus pulls into torvalds/linux
|
v
pr-tracker-bot confirms merged into
commit bf1079577a116f0685e7025b9ee2547345ee1c63
Old race Fixed race
---------- --------------
Task exit on CPU B Task exit on CPU B
| |
check ownership lock rq
(no lock) check ownership
| |
move_task (still on list?) move_task_locked
| |
--> spurious abort unlock rq
--> safe
Highlight:风险与注意点
- race 修复是否覆盖所有路径:移动到 queue lock 之后要确认 read/write 路径的并发模型一致;如果仍存在 RCU 释放与锁顺序倒置,可能引入新死锁,需要后续 review 重点看 lockdep 报告。
- capability 标记向后兼容:新增 sleepable capability 后,老 userspace 不会感知;如果 BPF prog 在老内核上编译并启用 sleepable 路径,运行时行为差异要在 libscx 文档里写清楚。
- 示例调度器的 vtime 修正:cgroup migration 的记账修复是数值精度问题,需在 CI 上跑 vtime 平衡性测试,确认跨迁移累计误差为零。
- tooling 头同步:scx 仓库与内核头的同步是手工过程,未来可以考虑加自动化检查,避免再次漂移。
- pr-tracker-bot 消息:仅是自动回执,不携带技术细节,不要把它当成讨论内容。
版本变化
本系列为单 tag 内的累积 fixes,没有 vN → vN+1 的迭代;但顶端 commit 列表可视为按时间排序的演进:
fab183d632 for-7.3-arena-args merge base
|
+-- race fix on dispatch queue move
|
+-- sched-ext.rst + cgroup-v2 BPF doc
|
+-- cgroup_set_bandwidth sleepable + cap marker
|
+-- tooling header sync (scx compat)
|
+-- example scheduler: timer re-arm + vtime credit on cgroup migrate
|
+-- finish_dispatch() kernel-doc (@slice, @vtime)
068e5a0bc5 tip
与其他相关 patch 系列的关联
- 与
for-7.3-arena-args(基线)形成「先合特性、再合 fixes」的两阶段节奏,是 sched_ext 维护者 Tejun 的常规流程。 - cgroup_set_bandwidth 的 sleepable 化与 cgroup v2 BPF 子系统文档同步,呼应 BPF scheduler 想深入 cgroup 控制的整体方向。
- tooling header 同步依赖 scx 用户态仓库(https://github.com/sched-ext/scx),内核与用户态的接口稳定性靠这类同步 patch 维持。
一句话总结
本文是 sched_ext 维护者 Tejun Heo 在 v7.3-rc1 前的 fixes pull request:修掉 dispatch queue move 的 race、放开 cgroup_set_bandwidth 的 sleepable 限制并新增 capability 标记、修复示例调度器的 timer 与 vtime 漏洞、收尾文档与 tooling 头,由 pr-tracker 自动确认已合入 torvalds/linux。