0/1 已展开

LLM 分析

sched/core:在 queued wakeup 路径上保留 wake flags

系列概况

  • 标题: [PATCH v2] sched/core: Preserve wake flags across queued wakeups
  • 作者: Shubhang Kaushik (Ampere) sh@gentwo.org
  • 版本: v2;base-commit = d96fcfe1b7f9(mainline origin/master)
  • 规模: 单 patch;3 个文件,+7/-18
  • 修改文件: include/linux/sched.hkernel/sched/core.ckernel/sched/sched.h
  • 代码统计: +7/-18
  • Message-ID: 20260713-b4-sched-ttwu-wake-flags-v2-1-76e23a8cc313@gentwo.org
  • 完整性: 完整(含 commit message、Signed-off-by、base-commit、change-id、v1 链接、perf bench/hackbench 测试结论)

补丁目的

让 queued remote wakeup 在被 sched_ttwu_pending() drain 时,传入 ttwu_do_activate() 的 wake flags 与直接 try_to_wake_up() 路径保持一致,避免两条路径在目标 CPU 非空闲时给出不同的抢占决策。

旧流程的问题

旧实现只在 task_struct 中保留 sched_remote_wakeup:1 一个布尔位,仅记录 "wakee 是否被迁移过"。其余 WF_TTWU / WF_SYNC / WF_RQ_SELECTED 等激活阶段需要的 flag 全部被丢弃。

当 wakeup 跨 CPU 被排入 wakelist,等到目标 CPU自行 drain 时只能传回 WF_MIGRATED0,这与 direct wakeup 把完整 wake_flags 传给 ttwu_do_activate() 的做法不一致,从而在目标 CPU 非空闲场景下产生不同抢占结果。

新流程

sched_remote_wakeup:1 替换为独立的 u8 sched_remote_wakeup_flags,使用新的 WF_TTWU_QUEUE_MASK__ttwu_queue_wakelist() 阶段截取并保存真正影响激活路径的位;drain 时再原样回传给 ttwu_do_activate()

WF_CURRENT_CPU 故意不放进 mask——它只是 CPU 选择阶段的放置提示,进入激活流程已无意义。

   direct try_to_wake_up()             queued remote wakeup
   ---------------------               ----------------------
   wake_flags (full set)               p->sched_remote_wakeup_flags
        |                              = wake_flags & WF_TTWU_QUEUE_MASK
        v                                       |
  ttwu_do_activate(rq,p,wake_flags,..)           v
                                       sched_ttwu_pending() (target CPU)
                                                  |
                                                  v
                                       ttwu_do_activate(rq,p,
                                              stored_flags,..)
                                                    |
                                                    v
 consistent preemption
                                            decision w/ direct path
   mask membership:
   WF_TTWU        | YES | -- activation matters
   WF_SYNC        | YES | -- activation matters
   WF_MIGRATED    | YES | -- was already kept
   WF_RQ_SELECTED | YES | -- activation matters
   WF_CURRENT_CPU | NO  | -- placement hint only

关键实现

kernel/sched/sched.h 新增掩码:

#define WF_TTWU_QUEUE_MASK (WF_TTWU | WF_SYNC | WF_MIGRATED | WF_RQ_SELECTED)

kernel/sched/core.c 写入端(__ttwu_queue_wakelist):

p->sched_remote_wakeup_flags = wake_flags & WF_TTWU_QUEUE_MASK;

读取端(sched_ttwu_pending):

int wake_flags;
wake_flags = p->sched_remote_wakeup_flags;
ttwu_do_activate(rq, p, wake_flags, &rf);

include/linux/sched.h 把字段从 unsigned sched_remote_wakeup:1 改为独立的 u8 sched_remote_wakeup_flags,并删除与之配套的、关于 p->on_cpu 不再序列化 wakelist 的长篇注释;v2 把字段挪出 scheduler word,避免再与该 bitfield 的串行化约束挂钩。

类比

把 wake flags 想成快递面单上的处理标签。直送路径就像快递员看到 "加急 / 同步 / 已选路线 / 已转运" 全部标签后决定何时投递;旧 queued 路径相当于把面单撕掉只剩 "是否转运",目的分拣站只看到这个标签来处理。

新版本相当于给转运件保留了一份精简过的面单副本(WF_TTWU_QUEUE_MASK),让分拣站能和直送件做出一致的优先级判断。而 WF_CURRENT_CPU 不进副本,是因为它只是 "去哪个分拣中心" 的提示;一旦进了分拣流程,再保留这个地址已经没有意义。

Highlight:风险与注意点

  • 行为变化面:queued wakeup 的 preemption 决策会更接近 direct wakeup,可能让以往依赖旧默认行为的 workload 见到细微的延迟 /吞吐差异,需要重点 review 抢占敏感场景。
  • 字段体积与 bitfield 语义:从 1 bit 变 u8task_struct 体积开销;v2 已把它挪出 scheduler word,原先关于 "被 on_cpu 序列化" 的长注释被删除,需要确认 reviewer 理解字段位置变更。
  • 覆盖完整性WF_TTWU_QUEUE_MASK 当前含 4 个 flag;将来若给 ttwu_do_activate() 新增激活语义 flag,必须同步加入 mask,否则又会出现遗漏。
  • 测试覆盖:作者仅在 Ampere Altra 80 CPU ARM 服务器上跑 perf bench sched messaginghackbench,吞吐处于噪声范围;建议在 x86 NUMA 拓扑或抢占更敏感的内核构建下复测。
  • 可观测性:tracepoint / perf 等若记录 wake flags,需确认它们读到的是 drain 后的完整 mask,而不是被丢掉的其它位。

版本变化(v1 → v2)

  • sched_remote_wakeup_flags 移出 scheduler bitfields,作为独立 u8
  • 去掉 sched_ttwu_pending() 里不再需要的 reset。
  • 新增 WF_TTWU_QUEUE_MASK,明确跨 wakelist 保留哪些 wake flags。
  • 收紧 changelog,聚焦 direct 与 queued wakeup 之间的一致性。

一句话总结

把 queued wakeup 上保存的 wake flags 从 "是否迁移" 一位布尔扩展到 WF_TTWU_QUEUE_MASK,让 sched_ttwu_pending() drain 时传给 ttwu_do_activate() 的 flag 与 direct wakeup 路径保持一致,从而统一两条 wakeup 路径的抢占决策。