sched discussion
[RFC PATCH 0/2] sched: Document WF_SYNC wakeup placement semantics
LLM 分析
sched:WF_SYNC 唤醒放置语义文档化
系列概况
- 标题:
[RFC PATCH 0/2] sched: Document WF_SYNC wakeup placement semantics - 作者:Shubhang Kaushik (Ampere)
<sh@gentwo.org> - 版本:v1(RFC)
- 规模:2 patches;3 files changed, 150 insertions(+), 14 deletions(-)
- 修改文件:
Documentation/scheduler/index.rst、Documentation/scheduler/sched-wake-affinity.rst(新增)、kernel/sched/wait.c - 代码统计:docs +134,wait.c +16/-14
- Message-ID:
20260825-sched-wf-sync-doc-v1-0-f899edb44ff5@gentwo.org - 完整性:完整,3 封 RFC 邮件 + 1 封 maintainer 回复(回复正文被截断)
补丁目的
WF_SYNC 是同步 waitqueue 唤醒辅助(__wake_up_sync_key、__wake_up_locked_sync_key 等)传入 try_to_wake_up() 的标志位,含义是"调用方预期 waker 很快 schedule away"。当前 fair-class 下该标志如何影响 CPU 选择和唤醒抢占,没有文档;同时 kernel/sched/wait.c 注释错误地承诺"同步 wakee 不会被迁移到另一 CPU"。本系列:
- 新增
Documentation/scheduler/sched-wake-affinity.rst,沿try_to_wake_up()→select_task_rq_fair()→select_idle_sibling()→preempt_sync()调用链,描述 WF_SYNC 的实际行为; - 修正
kernel/sched/wait.c中两个__wake_up_*_sync_key的注释,删除错误的"no-migration"承诺。
不改变调度行为,仅把 WF_SYNC 定位为"non-binding fair-class hint"。
旧流程的问题
旧注释(kernel/sched/wait.c)原文:
The sync wakeup differs that the waker knows that it will schedule
away soon, so while the target thread will be woken up, it will not
be migrated to another CPU - ie. the two threads are 'synchronized'
with each other. This can prevent needless bouncing between CPUs.
问题:
- "will not be migrated to another CPU" 与
select_task_rq_fair()/select_idle_sibling()实际行为冲突。wake_affine()仅给出候选,最终由select_idle_sibling()决定,可能改放到 prev CPU、SMT 兄弟、甚至其他 LLC 域的 idle CPU。 - 注释把 WF_SYNC描述成"CPU 绑定约束",实际只是"启发式 hint"。
- futex、pipe、epoll、completion、vhost 等数十处同步 waitqueue 调用点可能基于错误注释形成错误的可移植性假设。
新流程
新文档明确 WF_SYNC 是非绑定 hint,并列出 fair-class 下的真实行为:
- CPU 选择:WF_SYNC 仅参与
wake_affine()偏差计算。wake_affine_idle()在rq->nr_running - cfs_h_nr_delayed(rq) == 1时倾向 waker CPU。wake_affine_weight()调整 effective load 比较(去掉当前任务负载、偏置 prev CPU)。select_idle_sibling()仍覆盖该候选,可能挑 prev CPU、SMT 兄弟或 search domain 内其他 idle CPU。
- 抢占:
preempt_sync()在 wakee已是 next buddy、当前实体运行 ≥sysctl_sched_migration_cost(带 WF_RQ_SELECTED 时 ÷4)时才请求 reschedule。 - 明确不保证的事项(文档列出):
- wakee 跑在 waker CPU;
- wakee 留在 prev CPU;
-避免迁移; - 与 waker 共核;
- 立即抢占当前任务。
try_to_wake_up(wake_flags=WF_SYNC)
|
|-- wakee queued? --> ttwu_runnable() --------> wakeup_preempt()
| (uses WF_SYNC)
|-- select_task_rq() --> select_task_rq_fair()
| |
| |-- record_wakee()
| |-- sync = (flags & WF_SYNC) && !PF_EXITING
| |
| |-- find_energy_efficient_cpu()? -> CPU
| |-- WF_CURRENT_CPU + allowed? -> CPU
| |-- want_affine = !wake_wide() && cpu allowed
| |
| |-- wake_affine_idle / wake_affine_weight
| | (bias under WF_SYNC)
| v | candidate CPU
| |
| v
| select_idle_sibling()
| |-- candidate idle? -> CPU
| |-- prev cache-affine idle? -> CPU
| |-- recent CPU idle? -> CPU
| |-- SMT sibling idle? -> CPU
| |-- other idle in sd_asym / sd_llc -> CPU
| v
| wakeup_preempt_fair() -> preempt_sync()
| (WF_SYNC, threshold)
v runqueue -> wakee scheduled later (placement NOT binding)
Patch 概览
- Patch 1/2 (docs):在
Documentation/scheduler/index.rst增加sched-wake-affinity条目;新增sched-wake-affinity.rst(133 行),从入口函数开始逐函数描述 WF_SYNC 行为。 - Patch 2/2 (wait.c):仅修改
__wake_up_sync_key/__wake_up_locked_sync_key注释,删除错误迁移承诺,明确"fair-class 把 WF_SYNC 当 hint,UP 可能避免一次不必要抢占",保留 SMP 内存屏障说明。
关键实现
select_task_rq_fair()中的 sync 推导:
sync = (wake_flags & WF_SYNC) &&
!(current->flags & PF_EXITING);
wake_affine_idle()在WF_SYNC且rq->nr_running - cfs_h_nr_delayed(rq) == 1时偏向 waker CPU。preempt_sync()仅在 wakee 早于当前实体且当前实体运行 ≥sysctl_sched_migration_cost(带WF_RQ_SELECTED时 ÷4)时返回 RESCHEDULE。- Patch 2/2 仍保留"wake up task 前执行 full memory barrier"语义,保证 waker 的状态变更对 wakee 可见。
类比
把 WF_SYNC 比作高铁站广播"某车次即将检票":广播只是提醒候车者准备登车,候车者最终是否在这班车、是否去别的站台、是否换乘,仍由检票口与站台空闲决定。旧注释把广播当成"锁定座位"的承诺,与现实不符;新文档承认它只是 hint。
再换一个:WF_SYNC 像 waker 把手机递给 wakee 时随口说"我马上去睡了"——wakee 醒来跑去哪里,由"咖啡馆座位图"(select_idle_sibling())决定,不是 waker 一句话能锁死的。
Highlight:风险与注意点
- 错误注释风险:旧注释诱导调用方误以为 WF_SYNC 提供 CPU 亲和保证,可能影响 futex、vhost、io_uring 等高频同步唤醒路径的性能假设;review 应追问现有调用方是否依赖错误承诺。
- preempt_sync 阈值隐式耦合 sysctl_sched_migration_cost:行为会随 sysctl 动态漂移,文档读者需意识到。
- 不修改行为:本系列只改文档/注释;未来若有人想把 WF_SYNC 从 hint 升为 binding policy,必须重审所有 waitqueue 同步调用点(文档已显式警告)。
- RST 文档命名偏窄:文件名
sched-wake-affinity.rst但内容覆盖 CPU 选择、idle 选择、抢占三部分;后续若拆分 wake-preemption 章节需要重构。 - maintainer 回复被截断:Madadi Vineeth Reddy 的回复只引用了 patch 描述与 index.rst diff 的开头,没给实质意见;review 信号缺失,重要性判断主要依赖 cover letter。
版本变化
首版 v1(RFC),无历史版本。
一句话总结
RFC 用文档和注释把 WF_SYNC 明确为 fair-class 唤醒放置与抢占的非绑定 hint,纠正 kernel/sched/wait.c 中"同步 wakee 不会被迁移"的过时承诺,不触动调度行为。