sched discussion
[PATCH RESEND] sched: Move some scheduler fields to new static branch API
LLM 分析
Linux scheduler:迁移 static_key → static_branch API
系列概况
- 标题:
[PATCH RESEND] sched: Move some scheduler fields to new static branch API - 作者: Hongyan Xia
<hongyan.xia@transsion.com> - 版本: RESEND(无 v 编号,无 series index/total)
- 规模: 单 patch;RESEND 备注说明原是更大的 series,本次拆分单独重发
- 修改文件:
kernel/sched/core.c、kernel/sched/fair.c - 代码统计: 13 行新增 / 13 行删除(core.c 18 行变更,fair.c 8 行变更)
- Message-ID:
20260819080932.11564-1-hongyan.xia@transsion.com - 完整性: patch 文本完整;thread 中多条回复正文在 lore 上被截断(被引用上下文不全)
补丁目的
把 kernel/sched/ 中仍使用老 static_key_* 抽象的两处静态分支迁移到新的 static_branch_* API:
__cfs_bandwidth_used直接以struct static_key定义并以static_key_false/slow_*操作 —— 这条已经被标记 deprecated,是真正的 fix。sk_dynamic_*使用static_key_{enable,disable},未明确 deprecate,但作者趁此机会统一到static_branch_*,保持代码风格一致。
作者在 commit message 中明确写明 "No functional change",因此这个 patch 是可读性 + 一致性改进 + 顺手清掉 deprecated 用法。
旧流程的问题
老 static_key 抽象要求开发者:
- 手动声明
struct static_key sk;(不带初始化) - 调用时取地址
&sk.key - 读侧用
static_key_false()、写侧用static_key_slow_inc_cpuslocked()/static_key_slow_dec_cpuslocked()
这种"裸 struct + 显式 &" 的写法散布在 kernel 中,新人难以一眼看出"这是一个 jump label"。新 static_branch_* 系列把声明 (DEFINE_STATIC_KEY_FALSE) 和读写 (static_branch_unlikely、static_branch_*_cpuslocked) 统一在一组语义清晰的 API 下,更易读、与其他子系统风格一致。
新流程
改名映射关系:
| 老调用 | 新调用 |
|---|---|
struct static_key sk; | DEFINE_STATIC_KEY_FALSE(sk); |
static_key_false(&sk) | static_branch_unlikely(&sk) |
static_key_slow_inc_cpuslocked(&sk) | static_branch_inc_cpuslocked(&sk) |
static_key_slow_dec_cpuslocked(&sk) | static_branch_dec_cpuslocked(&sk) |
static_key_enable(&sk.key) | static_branch_enable(&sk) |
static_key_disable(&sk.key) | static_branch_disable(&sk) |
语义保持不变:声明成默认 false,慢路径在 inc/dec 时改写 jump label 目标;读侧分支仍 unlikely。
Patch 概览
只一封单 patch,无子 patch 列表。RESEND 备注里两点改动相对"原始系列":
- 把原来的 series 拆成单独 patch,便于 review。
- 顺手把
sk_dynamic_*也迁到新 API。
关键实现
/* kernel/sched/core.c:宏改名 */
-# define preempt_dynamic_key_enable(f) static_key_enable(&sk_dynamic_##f.key)
-# define preempt_dynamic_key_disable(f) static_key_disable(&sk_dynamic_##f.key)
+# define preempt_dynamic_branch_enable(f) static_branch_enable(&sk_dynamic_##f)
+# define preempt_dynamic_branch_disable(f) static_branch_disable(&sk_dynamic_##f)
__sched_dynamic_update 中五个 case(none / voluntary / full / lazy、加上 default 分支)保持原结构,只是宏名替换成 preempt_dynamic_branch_{enable,disable}。
/* kernel/sched/fair.c:cfs_bandwidth 入口 */
-static struct static_key __cfs_bandwidth_used;
+static DEFINE_STATIC_KEY_FALSE(__cfs_bandwidth_used);
static inline bool cfs_bandwidth_used(void)
{
- return static_key_false(&__cfs_bandwidth_used);
+ return static_branch_unlikely(&__cfs_bandwidth_used);
}
void cfs_bandwidth_usage_inc(void)
{
- static_key_slow_inc_cpuslocked(&__cfs_bandwidth_used);
+ static_branch_inc_cpuslocked(&__cfs_bandwidth_used);
}
void cfs_bandwidth_usage_dec(void)
{
- static_key_slow_dec_cpuslocked(&__cfs_bandwidth_used);
+ static_branch_dec_cpuslocked(&__cfs_bandwidth_used);
}
#ifdef CONFIG_JUMP_LABEL 分支保持不变;非 jump label 走 fallback 返回 false。
类比
jump label 就像大楼里可变的指示牌:
- 老 API 让你自己去建材市场买牌子、装到墙上、再去物业登记开关台账(
static_key_*)。 - 新 API 给你一个统一服务台(
static_branch_*),一句话"开/关"就行,台账自动维护。
这次 patch 就是把所有手工装配的指示牌统一换成服务台呼叫 —— 牌子指向没变、来往行人看到的箭头没变、只是姿势更优雅,物业也更开心。
Highlight:风险与注意点
- 邮件编码被 MUA 弄坏:transsion 的 Outlook 把 patch 编码成一种奇怪 quoted-printable(每行末尾
=0A=,包括最后一行),触发 Peter 的 review 脚本把整封邮件吃掉;Peter 已修脚本,但若 reviewer 工具链再次遇到类似 encoding,需要二次跟进。 sk_dynamic_*后续会被移除:Peter 提到 Mark Rutland 已有系列准备把它们大部分删掉,只保留 lazy check;本次改名是临时一致化,与 Mark 的清理系列存在重叠/对齐关系,作者应在 v2 中确认两者不会互相冲突。- commit message 缺乏 deprecation 上下文:Shrikanth 评审时希望补充"为什么 deprecated"的链接(如 Documentation 或 git blame 说明),否则 reviewer 难以验证迁移必要性。
cpuslocked路径需重点验证:本次替换直接影响 hotplug / cgroup 路径下的inc/dec_cpuslocked调用,需确认在CONFIG_JUMP_LABELoff 的 fallback 路径下仍正确返回 false,避免带宽控制误判。
版本变化
相对原始 series,RESEND 做了两点:
- 把整组 series 拆成单独 patch 提交,便于单点评审。
- 把
sk_dynamic_*也一并迁到static_branch_*,扩大了一致化范围。
v2 及以上版本未见(thread 中无 v2 标签邮件)。
一句话总结
把 scheduler 里仍用老 static_key_* 的 __cfs_bandwidth_used 与 sk_dynamic_* 统一迁到新的 static_branch_* API,无功能变更、纯可读性 + 一致性改进,并作为 Mark 后续清理系列的前置。
Review Flow
-----------
+---------+ +-----------+
| Hongyan | | Peter |
| Xia | | Zijlstra |
+----+----+ +-----+-----+
| |
| patch (RESEND) |
|------------------->|
| |
| MUA mangled QP |
| script chokes |
|<-------------------|
| |
| debug request |
|------------------->|
| |
| =0A= + =$ tail |
| issue explained |
|<-------------------|
| |
| (more replies, |
| several bodies |
| truncated in lore)|
+--------------------+
API Rename Map
--------------
struct static_key sk; --> DEFINE_STATIC_KEY_FALSE(sk);
static_key_false(&sk) --> static_branch_unlikely(&sk)
static_key_slow_inc_cpuslocked --> static_branch_inc_cpuslocked
static_key_slow_dec_cpuslocked --> static_branch_dec_cpuslocked
static_key_enable(&sk.key) --> static_branch_enable(&sk)
static_key_disable(&sk.key) --> static_branch_disable(&sk)