4c95380701f5(把 balance_scx() 折进 pick_task_scx())引入的回归:dispatch 在 ->pick_task() 内执行并释放 rq 锁,同核的 core-wide selection 因此交错、互相破坏状态。主修复让 core-sched pick 在 dispatch 释放过 rq 锁时返回 RETRY_TASK,Cc: stable # v6.19+。capacity_freq_ref 用作 map_util_freq() 的参考频率,而该函数恰好在 capacity_freq_ref 处饱和,导致 cpufreq boost 开启后实际频率到不了 boost 区间。rate_limit_us 是 unsigned int,32 位系统上乘 NSEC_PER_USEC 时按 32 位算术运算,写 4294968 会把 delay 从 4294968000 ns 回绕到 704 ns。[1]
sched_ext 的 core scheduling 支持自 4c95380701f5 ("sched/ext: Fold balance_scx() into pick_task_scx()") 起损坏。这次 fold 把 dispatch 放到 ->pick_task() 内部执行,而 dispatch 会释放 rq 锁,于是同核上的 core-wide selection 会交错执行、互相破坏状态——表现为 rq->core_pick 被清零时崩溃,或已 dequeue 的任务继续运行导致机器卡死(scx#3715)。
主修复(patch 0006)让 core-sched pick 在 dispatch 释放过 rq 锁时返回 RETRY_TASK,确保 selection 只在持续持锁期间提交 pick。前置补丁更新 core-sched pick 以处理丢锁的 pick(0001-0002),并修同一 fold 导致的相邻破坏(0003-0005)。
patch 0003 把 SCX_RQ_BAL_KEEP(指示 pick 继续运行前一个任务的 leftover)替换为 dispatch verdict(SCX_DSP_NONE/LOCAL/PREV)。rq 级 flag 只在 dispatch 和 pick 一一配对时有效,core scheduling 打破了这一前提:selection 经 dispatch 丢锁而交错,一个 pick 可能消费过期 flag、继续运行已 dequeue 的任务。修复让该决策跟随产生它的 dispatch 一起传播,scx_dispatch_sched() 和 balance_one() 返回显式 verdict。(Tejun Heo,6 补丁系列)Fixes: 4c95380701f5,Cc: stable # v6.19+。[1]
sashiko AI 在 review patch 0006(rq->core_pick corruption 修复)时标出一个 High 风险:core scheduling 下 sibling CPU 执行 core-wide pick 时,pending kick-sync 操作被静默忽略丢失,破坏 scx_bpf_kick_cpu() 的等待保证。
[2]
Tejun Heo 8 月 2 日向 Linus 发出 GIT PULL(tags/sched_ext-for-7.2-rc6-fixes),pr-tracker-bot 确认合入 torvalds/linux(commit be76b516e681)。这批 6 个补丁把 w29/w30 报告过的修复带入 v7.2-rc6:
Skip sub-disable teardown for never-linked)、SCX_OPS_SWITCH_PARTIAL root 下非 ext 任务被标 ENABLED 却留在自己 class(Don't enable non-ext tasks in the sub-sched task loops)、子调度器 disable 路径静默改写活任务策略(Reject setting disallow from init_task outside the enable path);scx_cgroup_lock()、cgroup teardown 排空 cpu controller 文件、并发 cpu.weight 写,靠重排锁序修复(Take cgroup_lock() first);Mark waker CPU busy when selected in WAKE_SYNC case,w30 报告的 Kuba Piecuch 补丁);这批合入意味着上几期 sub-scheduler 生命周期 + cgroup lock + idle 跟踪的修复全部进入 v7.2-rc6。[3]
[4]
上期 w31 因当时只有 review 收齐、还需 rebase 而删去未报。本周 Mark Rutland 完成 rebase 并出 v2(8 月 3 日):rebase 到 v7.2-rc4 以避开 powerpc 冲突(a2c02aa0c6ca),补上已有的 R-b 标签,修 typo,并按 Shrikanth 建议新增第 6 个补丁(简化 preempt model accessor)。系列从 5 补丁变为 6 补丁。
Mark 自己判断当前周期偏晚(tip:sched/core 基于 v7.2-rc1),询问 tip 侧是现在排队还是等 v7.3-rc1 后再重发。这是承接 w27 起报、w29 拿到 R-b、w31 需 rebase 的延续线索,本周 rebase 这一步完成。[4]
[5]
【问题】capacity_freq_ref(经 get_capacity_ref_freq() 暴露给 schedutil governor)由 9942cb22ea45 引入,是运行时不变的固定锚点。但 schedutil governor 把这个固定锚点用作 map_util_freq() 的参考频率,而该函数恰好在 capacity_freq_ref 处饱和。结果是 cpufreq boost 启用的系统在 schedutil governor 下实际频率到不了 boost 区间。
【修复方案】改用 policy-max 作为 map_util_freq 的参考频率,并允许 cpuinfo max 在 boost 禁用时回退到非 boost 值。实测:补丁前 time_in_state 显示 4723200(boost 频率)占用为 0;补丁后该频率有实际占用。依赖当前行为(只向上 bump)的驱动可能受影响,需在驱动侧处理。(Sibi Sankar / 高通 + Ananthu C V,2 补丁)
[6]
【问题】rate_limit_us 是 unsigned int。32 位系统上乘 NSEC_PER_USEC 时按 32 位算术运算,结果赋给 freq_update_delay_ns 后已回绕。写 4294968 会把 delay 从 4294968000 ns 回绕到 704 ns,schedutil 因此远比配置的更频繁更新。
【修复方案】新增 sugov_update_rate_limit_us(),在转换单位前把值拓宽到 u64,sysfs 更新和 governor start 两条路径都改走该函数。Fixes: 9bdcb44e391d。(Hui Su)v2 按 review 把 rate_limit_us cast 到 s64 以匹配 freq_update_delay_ns、补充 32 位算术说明、加上 Zhongqiu Han 的 R-b。
[7]
【问题】SCHED_RESET_ON_FORK 防止调度属性传播到子进程,该请求记录在 p->sched_reset_on_fork。sched_setparam() 用 SETPARAM_POLICY 更新调度参数时保留当前 policy 和 reset-on-fork 设置。但 __sched_setscheduler() 在拿到 task rq 锁之前就读取 p->sched_reset_on_fork,并发的 sched_setscheduler() 可能在这次读取之后修改该 flag,随后执行的 sched_setparam() 会用过期值把它覆盖回去。
【修复方案】记录调用方是否要求保留 policy,拿到 rq 锁后重新读取 reset_on_fork。early-exit 和 full update 两条路径都保留最近一次序列化写入的设置。Fixes: ca94c442535a,Reported-by: K Prateek Nayak。(Andrea Righi)
[8]
Cui Jian 报告 find_parent_sched() 解引用 cgrp->scx_sched 前没有判空,传 v1 cgroup ID 作 sub_cgroup_id 会触发 NULL 解引用导致崩溃。Zhan Xusheng(小米)回复指出 v1 cgroup 实际到不了这个函数:cgroup_get_from_id() 只在 v2 kernfs root 查找(kernfs_find_and_get_node_by_id(cgrp_dfl_root.kf_root, id)),v1 id 会得到 -ENOENT;即便找到,cgroup_is_descendant() 也会按 cgrp->root != ancestor->root 拒绝;scx_cgroup_lifetime_notify() 对 !cgroup_on_dfl(cgrp) 直接返回。Zhan Xusheng 同时指出:防御性检查本身无害,但 changelog 写成"可达崩溃"会误导 backport 和 CVE 决策。
Cui Jian 随后的 v2 把 changelog 改为"实际安全,加防御性检查"。这与 w29 的 se.load 重复补丁同类——报告的 bug 路径实际不可达,但防御性检查保留。[9]
本周核心演进是上面两节展开的 core scheduling 修复和 v7.2-rc6 合入。承接上期判断,本周的关键变化是 v7.2 维护周期接近尾声(rc6),上几期累积的 sub-scheduler 生命周期、cgroup lock、idle 跟踪修复批量进入主线;同时 for-7.3 侧 idle CPU 状态初始化 apply、rescue execution v2 进入 review。
idle CPU 状态初始化系列(上期 v2 报告,本周经 v3→v4)被 Tejun apply 到 sched_ext/for-7.3,补丁标题改为"Initialize idle masks as busy",核心不变:在 ops.init() 之前启用 idle tracking 并在 rq 锁下刷新每个在线 CPU,ops.update_idle() 通知延迟到完全启用后才开放。这条与 v7.2-rc6 合入的 WAKE_SYNC waker CPU busy 属同一 idle 跟踪失同步问题域。
rescue execution(上期 v1 报告,本周 v2)继续 Tejun 自己的补丁拆分 review(16 个回复),Andrea Righi 在 8 月 3 日参与讨论。proxy execution 共存 v10 本周 Tejun Heo 在 8 月 3 日做了详细 review(涉及 reject DSQ reenqueue path 的 scx_reenq_reject() 实现等),Andrea 8 月 5-6 日回应。
本周稳定性修复分三块:core scheduling 修复(见一、,6 补丁,Cc: stable # v6.19+);v7.2-rc6 修复批次合入(见一、);schedutil boost 频率、rate_limit_us 溢出、reset-on-fork 并发(见二、)。
selftests/sched_ext: Check skeleton open failure in exit test(Liang Luo,KylinOS)——exit.c 不查 exit__open() 返回值,返回 NULL(skeleton wrapper 分配对象或 open BPF ELF 失败)时下一行 SCX_ENUM_INIT() 经 skel->rodata NULL deref。其他 selftest 都有 SCX_FAIL_IF(!skel, ...) 守卫,唯独 exit.c 缺。Fixes: a5db7817af78。[10]
sched: adjust cfs_bandwidth layout to save memory(Hongling Zeng,KylinOS,RESEND v2)——pahole 显示 cfs_bandwidth 有 padding hole,调整布局从 240 字节降到 232 字节。period_timer 可能多碰一个 cacheline,但本就碰多条 cacheline 且非热路径。[11]
sched: pause KCOV in __schedule()(Karl Mehltretter,3/5)——kernel/sched/ 本身不插桩,但它调用的函数(sched_clock()、arch CPU-capacity helper、profile_hits())插了桩,preempt/schedule 路径会给 current 引入非确定性的覆盖数据。CONFIG_KCOV_SELFTEST 的 interrupt selftest 在 x86_64 defconfig QEMU 下因 arch_scale_cpu_capacity() 的虚假覆盖而失败;arm64 在 sched_clock() 出现同类泄漏。逐个给被调函数加排除会把改动散布到各 arch,因此改为在 __schedule() 入口统一暂停 KCOV。Fixes: 5c9a8750a640。[12]
sched/debug: Protect lockless rq->curr access in print_cpu()(Aaron Tomlin,v3 1/4)——print_cpu() 无锁解引用 rq->curr,经 task_pid_nr() 打印 PID。访问 /sys/kernel/debug/sched/debug 本就是 best-effort,但如果 CPU 上运行的任务并发退出且 refcount 降到零,put_task_struct() 会调 call_rcu() 安排 __put_task_struct_rcu_cb();print_cpu() 解引用时不持 RCU 读锁,RCU grace period 可能在此期间完成并经 free_task() 释放任务结构。[13]
sched: minor cleanups(Zhan Xusheng,小米,3 补丁)——删 v6.19 起无调用方的 sched_fair_runnable()(static inline 故从未告警);删 requeue_task_rt() 的无用 rq 参数;修 RT_GROUP_SCHED 块的倒置 #endif 注释。无功能变化。[14]
perf sched: Suppress latency table output when trace samples are missing(Aaron Tomlin)——延续上期,本周出到 v9(1/4)。[15]
Cc: stable # v6.19+),关注是否进 v7.2 最终版和 stable 回填范围,以及 sashiko AI 标出的 pending kick-sync 丢失 High 风险如何处理。for-7.3。[1] 原文: https://lore.kernel.org/all/20260807210221.232543-1-tj@kernel.org/
[2] 原文: https://lore.kernel.org/all/73f632a36560eddd78a0b82db78e4b8d@kernel.org/
[3] 原文: https://lore.kernel.org/all/178578257290.2780879.7865900681859315974.pr-tracker-bot@kernel.org/
[4] 原文: https://lore.kernel.org/all/20260803191731.3244294-1-mark.rutland@arm.com/
[5] 原文: https://lore.kernel.org/all/20260806044230.909961-1-sibi.sankar@oss.qualcomm.com/
[6] 原文: https://lore.kernel.org/all/20260805143942.805176-1-sh_def@163.com/
[7] 原文: https://lore.kernel.org/all/20260807082236.1076967-1-arighi@nvidia.com/
[8] 原文: https://lore.kernel.org/all/20260807093838.56002-1-cjian720@163.com/
[9] 原文: https://lore.kernel.org/all/20260807114534.1253158-1-zhanxusheng@xiaomi.com/
[10] 原文: https://lore.kernel.org/all/20260807013912.3178229-1-luoliang@kylinos.cn/
[11] 原文: https://lore.kernel.org/all/20260803074026.57701-1-zenghongling@kylinos.cn/
[12] 原文: https://lore.kernel.org/all/20260807205027.31972-4-kmehltretter@gmail.com/
[13] 原文: https://lore.kernel.org/all/20260808235522.380038-2-atomlin@atomlin.com/
[14] 原文: https://lore.kernel.org/all/20260804124947.3898447-1-zhanxusheng@xiaomi.com/
[15] 原文: https://lore.kernel.org/all/20260725160513.57477-1-arighi@nvidia.com/