sched_ext/for-7.2-fixes;patch 2 的 stable 目标按讨论扩到 v5.14+,patch 3 同时删除 tools autogen 头里的 SCX_RQ_BAL_KEEP。SCX_TASK_ENQ_WAKEUP 的表达方式。drm_sched_entity_pop_job() 在 spsc_queue_pop() 和 drm_sched_rq_pop_entity() 之间无锁,并发 push 把一个绝对 vruntime 又加上一次 min_vruntime,entity 被推到 rbtree 右端长期不被选中。Tvrtko Ursulin 的加锁分支在 90 分钟测试中无法复现。ops.core_sched_before() 参数顺序——Tejun Heo 的 4 补丁系列发现 scx_prio_less() 调用 ops.core_sched_before() 时把两个参数传反了,返回值因此按文档语义反向使用,自 v6.12 起存在;系列同时用 runnable_at 替换 core_sched_at 统一等待时间跟踪,并让跨调度器任务对按最近公共祖先排序,Cc: stable # v6.12+。build_sched_domains() 在 SD_SHARE_LLC 与 SD_ASYM_CPUCAPACITY_FULL 落到同一 domain 时二次 claim shared 对象导致 refcount 等于 CPU 数的泄漏,QEMU/virtme-ng arm64 上 boot 后和 12 次热插拔的泄漏归零。[1]
Tejun Heo 修复 4c95380701f5(把 balance_scx() 折进 pick_task_scx())引入的 core scheduling 损坏的 6 补丁系列,本周合入 sched_ext/for-7.2-fixes。Peter Zijlstra 给 patch 1、2 加 Acked-by;patch 2 的 Fixes tag 改指 539f65125d20 ("sched: Add core wide task selection and scheduling"),stable 目标从 v6.19+ 扩到 v5.14+。Andrea Righi 指出 patch 3 漏删 tools/sched_ext/include/scx/ 下 autogen 头里的 SCX_RQ_BAL_KEEP 枚举,Tejun 出 v2 一并删,8 月 12 日合入整个系列,Andrea 给整个系列 Reviewed-by。Cc: stable # v6.19+(patch 3、6 仍指向 4c95380701f5)。
sashiko AI 在审阅 patch 6(rq->core_pick corruption 修复)时标出的 High 风险(core scheduling 下 sibling CPU 执行 core-wide pick 时 pending kick-sync 被静默忽略)本周未见独立修复,关注是否随系列或后续补丁处理。
[2]
Andrea Righi 的 proxy execution + sched_ext 共存系列本周出 v11(8 月 10 日,15 补丁)和 v12(8 月 16 日)。设计核心:SCX_OPS_ENQ_BLOCKED 让 BPF 调度器接收 mutex 阻塞的 donor,donor→owner 交接建模为函数调用(donor 仍是 BPF 选中的运行实体,owner 只作核心内部执行上下文),rq->donor/rq->curr 区分调度与执行上下文,proxy-raced 远程迁移走 reject DSQ。v11 只有补丁本体和 sashiko 自动审阅,v12 把 v11 上 sashiko 标出的多个 High 风险写进 changelog。按主题归并,v12 的改动落在三块:
reject DSQ reason 生命周期——ops.enqueue() 同步再次拒绝任务时保留一次完整的 re-enqueue reason,只在任务离开 reject DSQ 后才清除已消费的 reason(sashiko 在 v11 标出 WARN_ON_ONCE(!reason) 会在下一 tick 误触发并永久丢失拒绝原因);rq-lock handoff 期间变为 migration-disabled 的被拒任务立即处理,只把活动 proxy 上下文留在 park 状态。
donor 调度上下文统一——protected-slice 准入、rescue 抢占、slice save/restore、bypass 处理改用 donor 调度上下文,rescue 运行时间记到被救援任务的调度器(原本记到 owner);__schedule() 在 rq->donor 变化后刷新 NOHZ tick 依赖,避免受 CFS bandwidth 约束的 donor 陈旧保持 tick 开启、让进入的 RT 任务无法进 NOHZ_FULL(v11 标出的 NOHZ_FULL isolation 破坏);ops.running()/ops.stopping() 跟踪 donor 上下文含解析成功的 blocked donor。
唤醒与锁序——唤醒的 proxy donor 在替换 rq->donor 前先 dequeue,避开 blocked_lock 下的回调和 donor 短暂重入队列;恢复调 proxy_resched_idle() 前退出 mutex proxy-lock 作用域,避开 raw spinlock 下的调度类回调;scx_qmap blocked-donor 快路径对缺失的 eligible self cid 加固;SCX_TASK_ENQ_WAKEUP 移到 bit 16 给 task-state 和 re-enqueue-reason 扩展留位。
Tejun Heo 在 8 月 16 日对 v12 做详细审阅,多数是注释和命名意见,两个实质问题待定:
sched_change_begin() 在 DEQUEUE_CLASS && next_class != p->sched_class 时无条件调 sched_proxy_block_task() 结束 retained proxy 状态,会连带打断 fair/RT/DL 间 PI 转换中已有的 proxy 链。Tejun 问 John Stultz 这样是否正确。Andrea 提议把条件收窄到进出 ext_sched_class 的转换(p->sched_class == &ext_sched_class || next_class == &ext_sched_class),保留 fair/RT/DL 间的 PI proxy,只在进出 sched_ext 时清空。ops.running() 推迟条件——patch 7 的 set_next_task_scx() 用 (!p->is_blocked || !first) 控制 ops.running() 推迟到 proxy 解析成功后,Tejun 建议改写为 !(p->is_blocked && first) 更贴近意图并扩写注释。Andrea 已 ack 并改。其余是收尾意见:patch 9 的 reject DSQ reason 生命周期管理位置(scx_dispatch_dequeue() 不应管 reason,改在 dequeue_task_scx() 和 SCX_DEQ_CORE_SCHED_EXEC 路径显式清)、patch 10 的 scx_proxy_resolved() deferred 语义注释、patch 12 的 SCX_TASK_ENQ_WAKEUP 是否改成调用方传入的 wake_flag、blocked donor 的 remote-rq 放行条件是否覆盖同 CPU donor 运行 owner 场景。Andrea 多数已 ack,未决项是 class 切换条件收窄、SCX_TASK_ENQ_WAKEUP 改 wake_flag、blocked donor 的 remote-rq 放行条件。
[3]
Luke Wildhardt 8 月 8 日报告 v7.2 起 RX 9070 XT 在持续 GPU 饱和下桌面冻结,切换 gpu_sched.sched_policy 为 FIFO 可规避。回归由 45c211ddf92a(默认 FAIR)和 77a6809f1dc3(删 FIFO/RR)共同引入。Tvrtko Ursulin 先出 min_vruntime 处理补丁,后经 Luke 与 Claude 协作定位到具体竞态:
drm_sched_entity_stats::vruntime 在 entity 链入 rbtree 时是绝对值,idle 时是相对 min_vruntime 的值。save_vruntime() 出 idle 时转一次,restore_vruntime() 回来时转一次。drm_sched_rq_add_entity() 无条件调 restore_vruntime(),这只在 entity 已经过 save 时正确。
竞态窗口在 drm_sched_entity_pop_job():
spsc_queue_pop(&entity->job_queue); /* 队列变空 */
drm_sched_rq_pop_entity(entity); /* 持 entity->lock */两行之间无锁。并发 push 看到队列空,走 first-job 分支调 add_entity,对一个还没 save 的 vruntime 做 restore(把绝对值再加上一次 min_vruntime)。如果该 entity 是 leftmost,get_min_vruntime() 返回它自己的 vruntime,值翻倍。entity 被推到 rbtree 右端,持续负载下 min_vruntime 永远追不上,entity 长期不被选中。
Luke 加 instrumentation 在 60 秒 gameplay 中捕到 8 次 race、43315 次 restore;gfx_0.0.0 上的 kwin_wayland:cs0 是桌面冻结时停止响应的提交线程。Tvrtko Ursulin 在 8 月 12 日出加锁分支(drm-sched-fair-fixes),让 add 和 pop 两侧对称持 entity->lock。第一版只 pop 侧加锁,Luke 测试仍有 stuttering;Tvrtko 改成两侧对称加锁后,Luke 90 分钟跨多游戏加桌面多任务测试无法复现,确认修复。
Philipp Stanner 8 月 13 日发 v2 系列(drm/sched: Introduce more locking to entity,2 补丁),把 drm_sched_rq_pop_entity() 改为外部加锁调用、entity->last_scheduled 用 spinlock 保护,目标是消除 drm_sched_entity_is_idle() 里的 rmb 和 entity->stopped 的无锁访问,以及把 entity 的 idle completion 从 workaround 改回用锁。Tvrtko 当天给独立 drm/sched: Lock drm_sched_entity_is_idle() 补丁拿 spinlock。Philipp 在回复中提到自己早先的锁扩展补丁曾受社区冷遇,借此回归论证 drm_sched 需要优先保证形式正确性。这组加锁重构面向下一周期,v7.2 的实际修复是 Tvrtko 的加锁分支。
[4]
Tejun Heo 8 月 16 日的 4 补丁系列更新 core-sched 任务排序以适配 sub-scheduler 层级。scx_prio_less() 实现 prio_less() 语义(返回 true 表示 @a 优先级更低、应排在 @b 之后),而 ops.core_sched_before() 文档约定返回 true 表示 @a 应在 @b 之前运行。scx_prio_less() 原地把 op 返回值传出,运行时语义反了。补丁 1 调用时交换参数让语义对齐,同时翻转 scx_qmap 示例的比较方向——scx_qmap 当初按 wiring 而非文档写,两层反转抵消,行为正确;其他按文档写的调度器由本补丁修正。Fixes: 7b0888b7cc19 ("sched_ext: Implement core-sched support"),Cc: stable # v6.12+。
补丁 2 删掉 core_sched_at 和两个 touch 函数,默认排序改用 stall watchdog 已维护的 p->scx.runnable_at。原来的 stamp 在两种规则下维护(touch_core_sched() 在任务开始等 CPU 和 slice 用尽时戳,touch_core_sched_dispatch() 在每次 dispatch 时重戳),一次比较可能看到两种规则下的 stamp,不构成有意义的顺序;dispatch 重戳只对 bypass 模式下的比较有意义,多调度器让混合比较更常见。runnable_at 只在 enqueue 时刷新,任务占用 CPU 期间变陈旧,改用"运行中的任务排在所有等待任务之后"代替重戳。
补丁 3 让跨两个调度器的任务对按最近实现了 ops.core_sched_before() 的公共祖先排序。补丁 4 删掉 dequeue 路径里一个死的 core-sched 相关测试。
[5]
Breno Leitao 发正式补丁修 build_sched_domains() 的 sched_domain_shared 对象泄漏。根因:SD_SHARE_LLC 与 SD_ASYM_CPUCAPACITY_FULL 落到同一 domain 时(单 LLC 跨多种容量 CPU 的 arm64 拓扑,一个 MC domain 覆盖所有 CPU 同时带两个标志),init_sched_domain_shared() 二次 claim 同一 domain,第二次覆盖 sd->shared 不放第一次的引用,留下 refcount 等于 CPU 数、无人引用的对象逃过 claim_allocations() 回收。修复在 LLC 路径进入时检查 sd->shared 已非 NULL 则跳过(asym 路径已 claim 过)。QEMU/virtme-ng arm64 上,boot 后泄漏从 1 降到 0,12 次热插拔后从 13 降到 0。Fixes: 9e005ed21152,patch 干净合入到 v7.2-rc7 和 linux-next。
[6]
【问题】libbpf 解析 kfunc extern 时会剥掉末尾 ___flavor 后缀,裸 ___v2 声明解析到 scx_bpf_dsq_move_to_local,其 BTF proto 没有 @enq_flags 参数。extern 永不匹配,bpf_ksym_exists() 在每个有 ___v2 kfunc 的内核上都返回 false,宏回退到 ___v1,静默丢弃 @enq_flags。
【修复方案】给 extern 加其他版本化 extern 用的 ___compat 后缀:scx_bpf_dsq_move_to_local___v2___compat。Tejun Heo 合入到 sched_ext/for-7.2-fixes,把 Fixes tag 改指实际合入的 860683763ebf(原 changelog 引的 e01a940b4813 不在上游树里),加 Cc: stable # v7.1+,scx_qmap 段落换成通用影响说明(合入分支里没有 needs_immed())。(Qiurong Fang,KylinOS)
[7]
【问题】scx_bpf_dsq_reenq() 用 KF_IMPLICIT_ARGS 注册,内核 BTF proto 不含尾部的 bpf_prog_aux 参数。___compat extern 显式声明了该参数,libbpf 无法匹配 proto,weak extern 在每个内核上都保持未解析,wrapper 永远走旧 fallback——禁用 scx_qmap 的 lowpri 机制,非本地 reenq 对每个有该 kfunc 的内核都报"kernel too old"。
【修复方案】extern 去掉显式 aux 参数,调用点同步去掉 NULL。顺手把注释里的 v6.20 改成 v7.1。Fixes: 9c34c5074d1b,Cc: stable # v7.1+,合入到 sched_ext/for-7.3。(Tejun Heo)
[8]
【问题】scx_bpf_cid_to_cpu()、scx_bpf_cpu_to_cid()、scx_bpf_cid_topo() 归在 scx_kfunc_ids_cid 集合,但 scx_kfunc_context_filter() 不查这个集合。filter 的首条规则把不在已知集合里的 kfunc 当非 SCX 放行,这三个 kfunc 可从任意 struct_ops 程序调用(如 TCP 拥塞控制程序)。
【修复方案】把 scx_kfunc_ids_cid 加入 filter 的已知集合,与 in_any、in_idle 同处理。Fixes: e9b55af47edf,合入到 sched_ext/for-7.3。(Qiurong Fang,KylinOS)
[9]
【问题】scx_fork() 在 scx_init_task_enabled 置位时初始化任务,但 scx_cancel_fork() 只在 scx_enabled() 为真时才调 ops.exit_task()。在 enable 窗口(释放 scx_fork_rwsem 到置 __scx_enabled 之间)失败的 fork 跑了 ops.init_task() 却不跑 ops.exit_task()。
【修复方案】scx_cancel_fork() 改为以 scx_init_task_enabled 为条件。Fixes: 4269c603cc26,Cc: stable # v6.12+,合入到 sched_ext/for-7.3。(Qiurong Fang,KylinOS)
[10]
【问题】scx_process_sync_ecaps() 调 ops.sub_ecaps_updated() 前,把 dispatch context 设到从 llist node 取回的 target CPU 的 pcpu->dsp_ctx。但 dispatch kfunc 用 this_cpu_ptr() 解析自己的 context,dispatch buffer 也在其中,context 是 per 执行 CPU 的。core scheduling 起 dispatch_core_pick() 会为 sibling rq 跑 balance_one();为 sibling 处理 sync 时,执行 CPU 的 context 没设好就调 op,dispatch kfunc 在 NULL 或陈旧 rq 上误操作。NULL rq 经 scx_bpf_dsq_move_to_local() 进 task_can_run_on_remote_rq() -> cpu_of(NULL) 在 pick 路径 oops;陈旧 rq 则消费到错误的 runqueue。与 3dd52416e44a 修复的 this_rq() 假设属同一类 bug。
【修复方案】改用执行 CPU 的 dsp_ctx,与 scx_dispatch_sched() 对齐;记录的 rq 仍指向被 sync 的 CPU,dispatch 仍以该 rq 为目标。Fixes: b81a6c018cde,David Carlier 报告,合入到 sched_ext/for-7.3,Andrea Righi 给 Reviewed-by。(Tejun Heo)
[11]
【问题】scx_bpf_dsq_reenq() 排一个 deferred reenq(dru)在 run_deferred() 里跑,不在 ops.dispatch() 里。DSQ 在 dru 跑前被销毁时,process_deferred_reenq_users() 看到 dsq->id == SCX_DSQ_INVALID 触发 BUG_ON。destroy_dsq() 不 flush 挂起的 dru。
【修复方案】在 SCX_DSQ_INVALID 时 continue 跳过。Tejun Heo 审阅指出 v1 把所有 SCX_DSQ_FLAG_BUILTIN 都跳过太宽,合法情况下唯一能出现在这里的 builtin-flagged 值就是 SCX_DSQ_INVALID,其余状态不该出现,应保留 BUG_ON。作者 v2 按此改窄,只跳 SCX_DSQ_INVALID。sashiko 在 v2 审阅中标出 TOCTOU(dsq->id 两次无锁读,中间被置 SCX_DSQ_INVALID 仍可能触发 BUG_ON)和 pre-existing 的 UAF(dru 锁外解引用 dsq->id,RCU grace 期间 free_dsq_rcufn 可能 kfree),后者属既有问题,本周补丁未触及。(Tao Cui,KylinOS)
[12]
fcg_cgroup_set_weight() 更新 cgc->weight 和父的 child_weight_sum,但没抬升 hweight_gen,cgrp_refresh_hweight() 缓存的 hweight 在下次任务激活抬升 generation 前一直陈旧。对任务从不经历 0→n runnable 转换的持续 busy cgroup,cpu.weight 改动完全不传播到调度。补丁在 weight 变更时 __sync_fetch_and_add(&hweight_gen, 1)。作者在 4 vCPU VM 上验证:D=800(按复利模型应是 800/900≈89%)实测只到 49%,补丁前 HWT update 为 0、分布不变,补丁后 hweight_gen 递增、refresh 重算。作者同时提出 budget clamp 在饱和下使分布趋于近乎相等的问题,Tejun 未在本周回复。合入到 sched_ext/for-7.3。
同作者第二个 scx_flatcg 补丁修 cvtime true-up 符号反 + u64 回绕:fcg_dispatch() 在 cgroup slice 过期或 DSQ 空时 true-up cvtime_delta,表达式 (cpuc->cur_at + cgrp_slice_ns - now) 符号反,CNS_EXPIRE 时 now 已过 cur_at + cgrp_slice_ns,u64 减法回绕;乘法保留二补码编码但除以 hweight 破坏它,每次 expiry 给 cvtime_delta 加约 2^64/hweight。补丁把 delta 算成 s64,用 fetch_and_add()/fetch_and_sub() 保持被除数为正(BPF 除法无符号)。Fixes: a4103eacc2ab,合入到 sched_ext/for-7.3。(Tao Cui,KylinOS)
[13]
print_dl_rq() 无锁解引用 cpu_rq(cpu)->rd 取 dl_bw。CPU 热插拔或 cgroup cpuset 重分区时,partition_sched_domains() -> cpu_attach_domain() -> rq_attach_root() 解绑 root_domain,refcount 归零时 call_rcu 安排 free_rootdomain。rq_attach_root() 原先用普通 C store 更新 rq->rd,没有 RCU 发布屏障,CPU 或编译器重排可能让新 rq->rd store 在 rd->dl_bw 初始化写之前可见。debugfs 读文件时不持 RCU 读锁,grace period 可在期间完成并 kfree,UAF。
Aaron Tomlin(v4 1/5)改 rq_attach_root() 用 rcu_assign_pointer(rq->rd, rd) 发发布屏障,print_dl_rq() 在 RCU 读临界区里 READ_ONCE 取 rd 并判空。patch 2 同类修 print_cpu() 对 rq->curr 的无锁解引用(任务退出并发 + refcount 归零时 put_task_struct() 调 call_rcu 安排 __put_task_struct_rcu_cb(),print_cpu() 不持 RCU 读锁,grace 期间 free_task() 释放任务结构)。Daniel Vacek 审阅建议用 guard(rcu)() + rcu_dereference() 更简洁,Aaron 采纳并计划给 struct rq 的 rd 加 __rcu 标注。Fixes: 02968ccf7b80。(Aaron Tomlin,v4 系列)
[14]
CONFIG_CPUSETS=n 时 rebuild_sched_domains() 不取 CPU hotplug 锁,读 /proc/sys/kernel/sched_rt_runtime_us 经 sched_rt_handler() -> partition_sched_domains() -> sched_cache_set() -> static_key_enable_cpuslocked(&sched_cache_present) 触发 lockdep backtrace。sched_cache_set() 在 sched_init_domains() 早期启动路径也调,那时只持 sched_domains_mutex,因用户空间未运行无 hotplug 故不告警。
Sebastian Andrzej Siewior v1 在 partition_sched_domains() 加 guard(cpus_read_lock)()。Yu C Chen 指出 partition_sched_domains() 文档约定"Call with hotplug lock held",更合理的位置是 rebuild_sched_domains() 在 CONFIG_CPUSETS=n 分支加锁,只影响该分支。v2 按此改:rebuild_sched_domains() 在 CONFIG_CPUSETS=n 实现里加 guard(cpus_read_lock)(),partition_sched_domains() 不动。Fixes: a7660ce1590fc。(Sebastian Andrzej Siewior,Linutronix)
[15]
Vincent Guittot 的补丁合入 tip:sched/core(commit 333238da9a19):requeue_delayed_entity() 在算 update_entity_lag() 前不调 update_curr(),延迟实体可能看起来比实际更年轻、得到更少的等待补偿。补丁在算 lag 前先 update_curr(cfs_rq) 刷新到 now。
本周核心演进是上面两节展开的 core scheduling 修复合入、proxy execution v11→v12、core-sched 任务排序系列。关键变化是 v7.2 维护周期末段(rc6→rc7)把 core scheduling 修复推入 for-7.2-fixes;for-7.3 侧 proxy execution v12 把 v11 上 sashiko 标出的 NOHZ tick、rescue 记账、reject reason 多个 High 风险写进 changelog,并经 Tejun 8 月 16 日审阅。
sched_ext: Convert arena-pointer interfaces to __arena arguments(Tejun Heo,3 补丁,for-7.3-arena-args)——cid-form 调度器把数据放 BPF arena,但内核与 BPF 间传 arena 对象的接口早于 bpf-next 刚合入的 __arena 参数支持:kfunc 把指针作 __ign 标量或 verifier-checked buffer,两侧手工在地址形式间重定位。系列把 ops_cid 的 set_cmask()/sub_caps_updated() 回调、sub-cap kfuncs、scx_bpf_cid_override() 全改成 __arena 参数,BPF 侧声明带 __arena 限定,scx_qmap 不再 cast 传递 arena 对象,手写转换 helper 删除。arena 参数地址翻译当前只在 x86-64 实现,用这些接口的 cid-form 调度器暂只在该架构加载。
sched_ext: Dispatch path follow-ups(Tejun Heo,3 补丁,for-7.3)——core scheduling 修复的后续。patch 1 修 kick_sync_wait_bal_cb():该 callback 假定在 rq 自己的 CPU 上跑(快照在该 CPU 的 percpu 区,busy-wait 丢 rq 锁开 IRQ),但 dispatch 现在能在 callback 排队时丢 rq 锁,期间拿锁者(sched class 切换路径、scx task iterator)在释放时 flush 挂起的 balance callback,可能把它跑到外 CPU,比较无关快照,且执行 CPU 本身是 wait 目标时死锁。补丁在 cpu_of(rq) != smp_processor_id() 时直接返回,留 wait 状态不动。Fixes: 4c95380701f5,Cc: stable # v6.19+。patch 2 删掉 dispatch verdict 转换后 dispatch_pick() 里遗留的 keep_prev fixup。patch 3 把 balance 时代遗留的标识符重命名为 dispatch 术语。
sched_ext: Misc fixes(Tejun Heo,2 补丁,for-7.3)——patch 1 删 scx_root_disable() 里无锁的 scx_rq_clock_invalidate():该调用是对 rq->scx.flags 的 plain RMW,其他写者持 rq 锁,无锁更新会与并发 flags 更新竞争丢位;且冗余,下面的 dl_server rebalancing 循环每个 rq 锁,rq_unpin_lock() 在 unlock 时清 SCX_RQ_CLK_VALID,__scx_enabled 在函数靠后才关,clock 最终都会被作废。Fixes: 3a9910b5904d。patch 2 让 scx_bpf_events() 读调用程序所属调度器的事件计数器,而非总读 root 调度器的。
sched_ext: Make SCHED_CLASS_EXT select GENERIC_ALLOCATOR(Tejun Heo)——kernel/sched/ext/arena.c 用 gen_pool 分配器,只在 GENERIC_ALLOCATOR 设时构建。SCHED_CLASS_EXT 没 select 它,在无其他选择者的配置上链接失败:build_policy.o: undefined reference to 'gen_pool_create/for_each_chunk/destroy'。Fixes: 9eca087deb0b,kernel test robot 报告,合入到 for-7.3。
sched_ext: Move the config-off sub-cap kfunc stubs into sub.c(Tejun Heo)——CONFIG_EXT_SUB_SCHED=n 时 sub-cap kfunc 的 EOPNOTSUPP stub 原 #ifndef 在 ext.c,真实定义在 sub.c,移到 sub.c 让所有 sub kfunc 定义集中。纯代码移动。
本周稳定性修复分四块:core scheduling 修复合入(见一、,6 补丁,Cc: stable # v6.19+,patch 2 扩到 v5.14+);dispatch path follow-ups 的 kick_sync_wait_bal_cb 外 CPU 修复(见三、,Cc: stable # v6.19+);本周新报的 6 个 bug(见二、:dsq_move_to_local___v2 compat、dsq_reenq___compat extern、cid kfuncs context filter、exit_task leak、sub_ecaps_updated dsp_ctx、process_deferred_reenq_users BUG_ON);scx_flatcg 的 hweight_gen 与 cvtime true-up(见二、)。
selftests/sched_ext: Make numa idle validation race-free(Cheng-Yang Chou)——scx_bpf_pick_idle_cpu_node() 返回的 CPU 可能在 BPF 程序验证前被 idle-to-idle 重选再次广告为 idle,scx_bpf_pick_any_cpu_node() fallback 根本不 claim CPU,断言被选 CPU 不在 node 的 idle cpumask 里本身有竞态。改验证稳定的本地不变量:在非 idle 调度上下文跑 ops.select_cpu() 的 CPU 不应在其 node 的 idle cpumask 里。合入到 for-7.3。
selftests/sched_ext: Fix flaky ddsp failure tests on busy systems(Michal Blaszczyk,Google)——ddsp_vtimelocal_fail 和 ddsp_bogus_dsq_fail 在 scx_bpf_pick_idle_cpu() 找不到 idle CPU(返回负错误码)时跳过 scx_bpf_dsq_insert_vtime(),busy 系统上跳过本该验证的断言。补丁 fallback 到 prev_cpu 保证非法 dispatch 操作无条件执行。Fixes: a5db7817af78,合入到 for-7.3。
selftests/sched_ext: build BPF schedulers via the shared lib.bpf.mk(Ziyang Men,v3 4/4)——sched_ext 自带约 130 行 libbpf + bpftool + vmlinux.h + BPF 对象 + skeleton 构建机制,换成 include 共享的 tools/testing/selftests/lib.bpf.mk,sched_ext 成为继 selftests/cgroup 和 selftests/hid 后第三个 in-tree 消费者。28 个 skeleton 和 28 个 subskeleton 的公开 API 保持不变。
cgroup, sched: add BPF kfuncs for cgroup cpu controller(Ziyang Men,2 补丁)——仿 mm/bpf_memcontrol.c 的 memcg kfuncs 给 cpu cgroup 加 BPF kfuncs:CFS bandwidth 计数器是 tg->cfs_bandwidth 的普通字段留给 BPF 直读;新增一个 kfunc 算 throttled time(需跨所有 possible CPU 求和,用户态做不了);bpf_cpu_cgroup_cputime() 一次调用返回五个 base CPU 时间值。拿 rstat 锁的两个 kfunc 按 mm/bpf_memcontrol.c 的做法标 KF_SLEEPABLE。测试用 prog_tests/cgroup_iter_cpu。Suggested-by Shakeel Butt。
sched_ext: minor doc and comment fixes(Tao Cui,KylinOS,v2 2 补丁)——修 sched_ext 文档与注释里的过时引用:Documentation/scheduler/sched-ext.rst 的 events sysfs 路径和 show_state 示例(aborting 在 drgn bools 下打印为 False)、inlines.h 注释里把 scx_bpf_dsq_insert() 改指 scx_bpf_sub_dispatch()、internal.h 用 %SCX_DEQ_SCHED_CHANGE 替代从未定义的 %SCX_DEQ_SAVE 并扩写 @name 覆盖 sub-scheduler。无功能改动,按 Tejun review 出 v2,rebase 到 sched_ext/for-7.3。[16]
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。
sched/debug: Protect lockless rq->curr access in print_cpu()(Aaron Tomlin,v3 1/4)——本周与 print_dl_rq 一起在 v4 系列里推进(见二、)。
docs: kernel-parameters: add CPU_FREQ, CPU_IDLE build options(Randy Dunlap,v2)——kernel-parameters 文档里多处用 CPU_FREQ/CPU_IDLE 描述参数,但 build options 列表里没这两项。v2 按 Rafael Wysocki 建议把描述写成"CPU frequency scaling is enabled"/"CPU idle time management is enabled"。
sched: Remove the unused preempt_offset parameter of __cant_sleep()(Boqun Feng,v4 08/17)——__cant_sleep() 的 preempt_offset 参数在所有调用点都是 0,删除并把 preempt_count() > preempt_offset 的比较改成 preempt_count(),清理掉多余的偏移比较。属 Boqun Feng 的 preempt-count 清理系列(17 补丁 v4),本周抓到的是第 8 个。
sched/fair: Remove duplicate check for busiest_cpu in active_load_balance_cpu_stop()(Xin Zhao,02/10)——cpu_active(busiest_cpu) 已保证 busiest_cpu 没下线,再查 busiest_cpu != smp_processor_id() 冗余。删除后 busiest_cpu 不再绑定到 smp_processor_id(),为后续 preempt active balancing 特性腾出位置。
sched: Update time before requeueing delayed entities(Vincent Guittot,tip:sched/core)——见二、。
ext_sched_class(保留 fair/RT/DL 间 PI proxy)、SCX_TASK_ENQ_WAKEUP 是否改成调用方传入的 wake_flag。关注 Andrea 是否出 v13、Peter Zijlstra 是否对 v12 给意见。for-7.2-fixes,patch 2 stable 扩到 v5.14+,关注是否进 v7.2 最终版以及回填到哪些 stable 版本;sashiko 标出的 pending kick-sync 丢失 High 风险是否随系列或独立补丁处理。ops.core_sched_before() 参数传反(自 v6.12+ 起存在),关注是否进 for-7.3 以及是否回填到 stable。[1] 原文: https://lore.kernel.org/all/20260807210221.232543-1-tj@kernel.org/
[2] 原文: https://lore.kernel.org/all/20260816173732.17162-1-arighi@nvidia.com/
[3] 原文: https://lore.kernel.org/all/TfhgV1W0W5LI6RWUO6J35B3R8QIYH_FN3Eihzdo_9PH39hfn1AVByT-QBPHmWiAR-L0Kqi2sppM_EhFPKwZPGmb5pFgpF2MrzeFzkZDmpG8=@proton.me/
[4] 原文: https://lore.kernel.org/all/20260816000527.988170-1-tj@kernel.org/
[5] 原文: https://lore.kernel.org/all/20260810-b4-sched_shared_leak-v1-1-3eacd249d0a3@debian.org/
[6] 原文: https://lore.kernel.org/all/20260811081143.578573-1-fangqiurong@kylinos.cn/
[7] 原文: https://lore.kernel.org/all/20260814205955.3490381-1-tj@kernel.org/
[8] 原文: https://lore.kernel.org/all/20260812061116.2691443-1-fangqiurong@kylinos.cn/
[9] 原文: https://lore.kernel.org/all/20260814032623.3834952-1-fangqiurong@kylinos.cn/
[10] 原文: https://lore.kernel.org/all/874500f5212b5d192092950ea8d284b8@kernel.org/
[11] 原文: https://lore.kernel.org/all/20260811075913.344033-1-cui.tao@linux.dev/
[12] 原文: https://lore.kernel.org/all/20260814144116.2767304-1-cui.tao@linux.dev/
[13] 原文: https://lore.kernel.org/all/20260810015812.428999-2-atomlin@atomlin.com/
[14] 原文: https://lore.kernel.org/all/20260813073855.ji2UrtVh@linutronix.de/
[15] 原文: https://lore.kernel.org/all/178673615898.442315.12755541915005920303.tip-bot2/
[16] 原文: https://lore.kernel.org/all/20260813230123.2069719-1-cui.tao@linux.dev/