sched discussion
[PATCH] sched/deadline: Use revised wakeup rule only for running dl_server
LLM 分析
sched/deadline:修订后的唤醒规则只对正在运行的 dl_server 生效
系列概况
- 标题:[PATCH] sched/deadline: Use revised wakeup rule only for running dl_server
- 作者:Gabriele Monaco gmonaco@redhat.com
- 版本:v1(单 patch,无版本号字段)
- 规模:1 个文件,+2/-1 行(
kernel/sched/deadline.c中update_dl_entity的一个分支条件) - 修改文件:
kernel/sched/deadline.c - 代码统计:
2 insertions(+), 1 deletion(-),外加 commit message 与 Tested-by/Acked-by 等签名行 - Message-ID(首封):
20260522125833.264145-1-gmonaco@redhat.com - 完整性:完整可分析。包含初版 patch、两位 reviewer 的答复(Acked-by、Tested-by)、作者 ping maintainer、maintainer 安排合并、tip-bot 自动发布到
sched/urgent的通知
补丁目的
这条 patch 是对上游 commit 14a857056466 ("sched/deadline: Use revised wakeup rule for dl_server") 的修正。
该上游 commit 改写了 update_dl_entity() 中的判定条件,把"修订后的 wakeup 规则"应用到了所有 deferrable server:
- 旧条件:
!dl_is_implicit(dl_se) || dl_se->dl_defer - 含义:只要这个 dl 实体不是 implicit,或者它本身就是一个 deferrable server,就走 update_dl_revised_wakeup。
问题在于:dl_defer == 1 只能说明"这是一个可以延期的 server",并不代表"它当前正处于运行态"。当一个 server 一开始就发生 deadline 溢出但 dl_defer_running == 0 时,上游逻辑会错误地把它当作"正在运行的 server",直接入队并触发 boost,破坏了 defer 语义和文档化的状态模型。
本 patch 的目标:把这条规则收紧为"只有当 server 是 deferrable 且当前正在 running 时,才走 revised wakeup rule"。也就是把条件改成:
if (unlikely((!dl_is_implicit(dl_se) ||
(dl_se->dl_defer && dl_se->dl_defer_running)) &&
...))
旧流程的问题
update_dl_entity(dl_se)
|
v
deadline expired / overflow?
|-- no --> normal path
|
v yes
check: !dl_is_implicit || dl_defer
|-- true --> update_dl_revised_wakeup()
| (no check on dl_defer_running)
v
non-running server with overflow
is enqueued as "running" -> wrong boost
后果:
- 状态机错乱:defer 规则要求 server 在未 running 时不应擅自 boost,但旧条件放行了这个情况。
- 可能被反复触发:带有过时 deadline 的 server 哪怕从未被选中运行,也会持续因 overflow 反复入队。
- 破坏
dl_server的文档化模型。
新流程
update_dl_entity(dl_se)
|
v
deadline expired / overflow?
|-- no --> normal path
|
v yes
check: !dl_is_implicit
|| (dl_defer && dl_defer_running)
|-- true --> update_dl_revised_wakeup()
| (only running servers)
v
dl_defer_running == 0 server stays quiet
dl_defer_running 作为新增的"运行标志"参与判定,把它从"一个描述 server 类别的字段",升级为"运行时可见的状态门控"。
Patch 概览
只改动一个判定表达式:
if (unlikely((!dl_is_implicit(dl_se) ||
(dl_se->dl_defer && dl_se->dl_defer_running)) &&
(dl_time_before(dl_se->deadline, rq_clock(rq)) ||
dl_entity_overflow(dl_se, rq_clock(rq))) &&
!dl_time_before(dl_se->deadline, rq_clock(rq)) &&
!is_dl_boosted(dl_se))) {
update_dl_revised_wakeup(dl_se, rq);
}
意图上保持其他前置判断不变,只在"启用 revised wakeup 规则的对象范围"上收紧一格。
关键实现
修改集中在 kernel/sched/deadline.c:update_dl_entity(),核心是把一个"OR 条件"拆成"二选一":
- if (unlikely((!dl_is_implicit(dl_se) || dl_se->dl_defer) &&
+ if (unlikely((!dl_is_implicit(dl_se) ||
+ (dl_se->dl_defer && dl_se->dl_defer_running)) &&
逻辑等价:
- 情形 A:
!dl_is_implicit(dl_se)-> 普通 dl 任务(旧路径保留) - 情形 B:
dl_defer && dl_defer_running-> 既是 deferrable 又处于 running 状态 - 情形 C:
dl_defer && !dl_defer_running-> 不再命中,避免错误的 wakeup/boost
这样:
- 真正的 dl_task 行为不变(情形 A)。
- 运行中的 dl_server 继续遵循修订后的 wakeup rule(情形 B)。
- 处于闲置/未激活状态的 dl_server 将走正常的 deadline 推进路径,不再误触发
update_dl_revised_wakeup()。
测试覆盖:
- 作者在 16 CPU 上跑
ksched_football:无回归,check-in 1 秒,game over 10 秒。 - John Stultz 在 64 vCPU guest 上同样验证通过(提供 Tested-by)。
- rt_stall sched_ext selftest 在该机器上原本就不是稳定高于 4%,与本 patch 无因果关系。
类比
把 dl_server 想成公司里负责"代管任务配额"的项目经理(deferrable server)。dl_defer 是他的岗位资质(能不能代管),dl_defer_running 是他今天是否在岗。
旧逻辑像:只要他是项目经理(dl_defer),哪怕今天他请假了(!dl_defer_running),只要看到某个任务 deadline 过期了,就立刻去签字加塞(boost)。结果他在休假时也能动用公司资源,破坏规则。
新逻辑是:他必须今天在岗(dl_defer_running),才能执行"修订后的 wakeup 规则"。请假时就按普通流程处理,不擅自出手。
Highlight:风险与注意点
dl_defervsdl_defer_running的语义差异:dl_defer只是类型/能力位,写作或评审时极易把两者混用,写出像(dl_se->dl_defer)这样"看上去对、其实只在某些 server 上对"的判断。update_dl_revised_wakeup的副作用:被错误调用后会入队并触发 boost,可能引发真实负载下可观察到的延迟/优先级反转,不只是"理论 bug"。- 上游 commit 的回归定位:本 patch 写明
Fixes: 14a857056466,合入 stable 时需要排查该 commit 影响到的 stable 分支;只看 Fixes tag 不要忽视测试覆盖。 ksched_football的回归测试需要较大机器:单 CPU 或小机器上,defer server 触发概率低,可能测不出来;选择测试机型时要避免假阴性。rt_stallselftest 的基线:作者提醒它在该机器上原本就不稳,分析 selftest 失败时要先确认基线,不要立刻归咎于本 patch。- 维护路径走
sched/urgent:Peter Zijlstra 在评审中明确通过 sched/urgent 分支 tip,说明此问题被定位为可观察回归而不是普通清理,下游 stable/分发版应当同步回移。
版本变化
本线索只有 v1,没有 v2/v3。但维护过程中可观察到以下状态演变:
2026-05-22 author posts v1
2026-05-22 Andrea Righi replies (no ack/fix stance)
2026-05-25 Juri Lelli gives Acked-by
2026-07-29 author pings Peter (maintainer) after maintainer returns from vacation
2026-07-29 Peter agrees, suggests sched/urgent branch
2026-07-29 John Stultz adds Tested-by on 64 vCPU guest
2026-07-30 tip-bot2 posts commit 1842bf97af... to sched/urgent
最终通过 tip 的 sched/urgent 分支以 commit 1842bf97af109f5ebf830175c9725bf81ebb78b1 落地,由 Peter Zijlstra 提交,base-commit 8bc67e4db64aa72732c474b44ea8622062c903f0。
一句话总结
把 update_dl_entity 走"修订 wakeup 规则"的条件从"任何 deferrable server"收紧为"deferrable 且当前 dl_defer_running 的 server",修正上游 commit 14a857056466 对未运行 dl_server 的错误 boost,并通过 sched/urgent 通道推送修复。