0/2 已展开

LLM 分析

sched_ext:v7.3-rc1 修复合入

系列概况

  • 标题:[GIT PULL] sched_ext: Fixes for v7.3-rc1
  • 作者:Tejun Heo tj@kernel.org(维护者发起的 git pull 请求)
  • 版本:无版本号(一次性 fixes tag,针对即将发布的 v7.3-rc1)
  • 规模:4 个 commit,2 位贡献者;包含 1 个 race fix、1 个 capability 放开、tooling header 同步、example scheduler 修正、文档修正
  • 修改文件:覆盖 kernel/sched/ext.ckernel/sched/ext_idle.c、示例调度器(scx repo)、tooling 头文件、sched-ext.rst、cgroup-v2 文档
  • 代码统计:邮件正文只给出主题行级别的描述,未提供 diffstat;只能从 commit 数和作者清单推断为小规模修复集
  • 基线 commitfab183d632628381b466a41479489541ac0e29a0(for-7.3-arena-args 合入点)
  • 顶端 commit068e5a0bc57e57d24cbf38def29cc5fb4db9a0df(finish_dispatch() kernel-doc 修正)
  • Message-ID0f59915200a4239f27a624250c58dd6c@kernel.org
  • 完整性:仅给出 commit 主题行级摘要 + 作者清单,未列出每个 commit 的完整 diff 与 Fixes tag;下文以主题行为准

补丁目的

这一组 fixes 面向即将发布的 v7.3-rc1,要解决几类典型问题:

  1. 调度器误中止(spurious abort)——dispatch queue move 时的 task ownership 检查与任务退出或切换 sub-scheduler 之间存在 race,会触发本不该发生的 scheduler abort。修复点是把检查搬到 queue lock 之内。
  2. 能力受限——ops.cgroup_set_bandwidth() 实际运行在 sleepable 上下文,但旧版加载逻辑禁止 sleepable 实现,导致 BPF scheduler 想要订阅 cgroup 带宽变化却被拒绝。这一组放开限制并新增 capability 标记,让 userspace 能探测支持情况。
  3. 示例调度器与文档漂移——示例调度器忽略 timer re-arm 失败、cgroup migration 时 vtime 信用丢失;tooling header 与 scx 仓库累积的兼容性改进不同步;文档里出现引用不存在的字段,kernel-doc 缺少参数描述。

整体目标:在不引入新特性的前提下,把 v7.3 合并窗口里累积的小问题一次性收口,让 rc 阶段尽可能干净。

旧流程的问题

  • race window:dispatch queue move 在无锁状态下做 ownership 校验;当任务正在 exit 或迁移到另一个 sub-scheduler 时,校验结果与实际归属对不上,触发 scx_ops_error 一类中止。
  • 加载策略过严cgroup_set_bandwidth() 明明可以 sleep,BPF 程序却因为 scheduler 拒绝 sleepable impl 而无法 attach。
  • 示例代码与文档陈旧:示例 scheduler 的 timer 路径没处理失败重试,vtime 在 cgroup 迁移路径上有泄漏;tooling 头文件落后于 scx 仓库;文档自相矛盾或缺字段说明。

新流程

  • move_task_to_local_dispatch()(或等价路径)里,把 ownership 检查移到持锁区,先 lock 再校验,避免和 exit / sub-scheduler 切换交错。
  • 允许 cgroup_set_bandwidth 注册 sleepable 实现;在 sched_ext_ops 暴露的 capability 集合里增加对应标记,userspace 通过 SCX_OPS_* 探测。
  • 同步 scx tooling 头文件;示例调度器补全 timer 失败路径;在 cgroup migration 路径补回 vtime 信用;修正 sched-ext.rst 中的字段引用、补全 finish_dispatch()@slice / @vtime kernel-doc。
  • 最终 commit 068e5a0bc5 把所有文档收尾。

关键实现

race 修复(最核心的 bugfix)

/* before: check races with task exit / sub-sched switch */
if (!task_owned_by(sub_sched, p))
    return -EINVAL;
move_to_dispatch_queue(p);

/* after: check under the queue lock */
raw_spin_lock(&rq->lock);
if (!task_owned_by(sub_sched, p)) {
    raw_spin_unlock(&rq->lock);
    return -EINVAL;
}
move_to_dispatch_queue_locked(p);
raw_spin_unlock(&rq->lock);

要点:把跨 CPU / 跨 sub-scheduler 的归属判断放进与 rq 锁同位的临界区,保证它和 task exit、sub-sched 切换串行化。

cgroup_set_bandwidth 放开 sleepable

static int validate_ops(struct sched_ext_ops *ops)
{
    ...
    /* 旧逻辑:
     * if (ops->cgroup_set_bandwidth && !may_sleep)
     *     return -EINVAL;
     */
    /* 新逻辑:直接放行,capability 由 userspace 探测 */
}

同时在 capability mask 增加 SCX_OPS_CGROUP_SET_BANDWIDTH_SLEEPABLE(名称示意),让 libscx 等用户态运行时能条件启用 sleepable callback。

示例调度器与文档

  • timer re-arm 失败时打印警告并继续,避免静默丢失 tick。
  • cgroup migration:迁移出口补 vtime -= p->scx.vtime 或等价冲账,迁移入口重新记账。
  • finish_dispatch() kernel-doc 补齐 @slice@vtime 描述。
  • sched-ext.rst 删除/替换不存在的字段示例。

类比

这组 patch 就像一栋大楼交房前的「验房清单」:

  • race fix 相当于发现某扇门没装好——住户开门的同时邻居在换锁,结果锁匠把住户锁在外面。修法是给门装一道「同把锁」,住户开门和邻居换锁必须排队。
  • 放开 sleepable callback 相当于物业原本规定「所有报修必须站着干」,但有住户投诉说水管的活必须蹲下,物业修改规则并在租房合同里增加「允许跪式作业」条款,租客也能从合同封面看到是否支持。
  • 文档同步则是把宣传册和实际楼栋编号对齐,免得带人参观时指着不存在的房间。

流程图

                    Pull Request: sched_ext-for-7.3-rc1-fixes
                    base: fab183d632 (for-7.3-arena-args merged)
                    tip:  068e5a0bc5 (finish_dispatch() kernel-doc)
                                |
        +-----------------------+-----------------------+
        |                       |                       |
  Liang Luo (3)          Changwoo Min (1)        tooling sync (1)
  - race fix             - cgroup_set_bandwidth   - header compat
  - sched-ext.rst        sleepable + cap marker
  - cgroup-v2 BPF docs
        |
        v
    Linus pulls into torvalds/linux
        |
        v
  pr-tracker-bot confirms merged into
  commit bf1079577a116f0685e7025b9ee2547345ee1c63
       Old race                         Fixed race
   ----------                       --------------
   Task exit on CPU B              Task exit on CPU B
        |                                |
   check ownership                    lock rq
   (no lock)                          check ownership
        |                                |
   move_task (still on list?)         move_task_locked
        |                                |
   --> spurious abort                 unlock rq
                                      --> safe

Highlight:风险与注意点

  • race 修复是否覆盖所有路径:移动到 queue lock 之后要确认 read/write 路径的并发模型一致;如果仍存在 RCU 释放与锁顺序倒置,可能引入新死锁,需要后续 review 重点看 lockdep 报告。
  • capability 标记向后兼容:新增 sleepable capability 后,老 userspace 不会感知;如果 BPF prog 在老内核上编译并启用 sleepable 路径,运行时行为差异要在 libscx 文档里写清楚。
  • 示例调度器的 vtime 修正:cgroup migration 的记账修复是数值精度问题,需在 CI 上跑 vtime 平衡性测试,确认跨迁移累计误差为零。
  • tooling 头同步:scx 仓库与内核头的同步是手工过程,未来可以考虑加自动化检查,避免再次漂移。
  • pr-tracker-bot 消息:仅是自动回执,不携带技术细节,不要把它当成讨论内容。

版本变化

本系列为单 tag 内的累积 fixes,没有 vN → vN+1 的迭代;但顶端 commit 列表可视为按时间排序的演进:

fab183d632  for-7.3-arena-args merge base
   |
   +-- race fix on dispatch queue move
   |
   +-- sched-ext.rst + cgroup-v2 BPF doc
   |
   +-- cgroup_set_bandwidth sleepable + cap marker
   |
   +-- tooling header sync (scx compat)
   |
   +-- example scheduler: timer re-arm + vtime credit on cgroup migrate
   |
   +-- finish_dispatch() kernel-doc (@slice, @vtime)
068e5a0bc5  tip

与其他相关 patch 系列的关联

一句话总结

本文是 sched_ext 维护者 Tejun Heo 在 v7.3-rc1 前的 fixes pull request:修掉 dispatch queue move 的 race、放开 cgroup_set_bandwidth 的 sleepable 限制并新增 capability 标记、修复示例调度器的 timer 与 vtime 漏洞、收尾文档与 tooling 头,由 pr-tracker 自动确认已合入 torvalds/linux。