0/2 已展开

LLM 分析

sched/core:移除 do_balance_callbacks() 中多余的函数类型转换

系列概况

  • 标题: [PATCH] sched: Remove unneeded function type cast in do_balance_callbacks()
  • 作者: Vladimir Zapolskiy vz@kernel.org
  • 版本: v1(单封 patch,未发 v2)
  • 规模: 1 file changed, 1 insertion(+), 1 deletion(-)
  • 修改文件: kernel/sched/core.c
  • 代码统计: +1 / -1
  • Message-ID: 20260819080159.105433-1-vz@kernel.org
  • 完整性: 完整;含 Signed-off-by、diffstat 与 hunk

补丁目的

该 patch 删除 do_balance_callbacks() 中给 head->func 赋值时遗留的显式函数指针类型转换。

旧流程的问题

历史上 head->func 来自 struct callback_head::func,类型是 void (*)(struct callback_head *),那时 cast 是为了让不同函数指针签名之间能强转。后来 commit 8e5bad7dccec ("sched: Introduce struct balance_callback to avoid CFI mismatches") 把容器换成 struct balance_callback、把 func 类型同步换成 void (*)(struct rq *),于是 cast 不再"改变函数类型",变成纯粹的死噪音。

新流程

func = head->func;

由于源类型与目标类型本就匹配,无需任何 cast就能直接赋值;CFI 校验也不会因为缺失 cast 而失败。

Patch 概览

本系列只有 1 个 patch,所有改动都集中在 kernel/sched/core.cdo_balance_callbacks() 中:

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
- func = (void (*)(struct rq *))head->func;
+ func = head->func;

关键实现

do_balance_callbacks() 在 rq 持锁状态下消费 balance_callback 链表,逐个调用每个回调:

static void do_balance_callbacks(struct rq *rq, struct balance_callback *head)
{
    void (*func)(struct rq *);

    lockdep_assert_rq_held(rq);
    while (head) {
        func = head->func;
        func(rq);
        next = head->next;
        head->next = NULL;
        head = next;
    }
}

赋值类型与 func 局部变量类型完全一致,所以这个 cast 是 callback_head 时代的遗留,可以安全删除。

类比

想象一个快递柜:每个格子(balance_callback)里放着一张"取件规则"纸条(func 签名)。前台服务员(do_balance_callbacks)取出纸条时原本还要再贴一张"请带身份证"的提示条(cast)。但换成新柜子(struct balance_callback)后,纸条本身就写明了规则,多贴的提示毫无意义——直接按纸条执行即可。删掉那张多余的提示条,就是这个 patch 做的事。

流程图

+----------------------------+
| struct balance_callback    |
+----------------------------+
| next  ---> next node       |
| func  ---> void(*)(rq)     | <-- type already matches target
+----------------------------+

 do_balance_callbacks(rq, head)
        |
        v
  func = head->func;          <-- no cast needed
        |
        v
  func(rq);                   <-- invoke callback |
        v
  advance head to next, repeat

Highlight:风险与注意点

  • 这是纯 cleanup,不改变行为;好处仅是阅读时少一个分散注意力的 cast。
  • 关键验证点:Peter Zijlstra 已经确认 cast 是 callback_head 时代的遗留,当前 balance_callback::func 天然匹配,无需 cast 也能通过 CFI 校验。
  • tip 公告里出现两个不同的 commit hash(4248f68...879eaa7...),说明该 patch 在 tip tree 里被重建/重放了一次;后续 bisect 时遇到两条相似 commit,不要误以为是重复提交。
  • 该 patch 已被并入 tip: sched/core,是 upstream 维护路径上的正式 commit。

版本变化

无(单封 patch,未发 v2)。

一句话总结

一行 cleanup:删掉 do_balance_callbacks() 里给 head->func 赋值时的冗余函数指针 cast,因为 struct balance_callback::func 的签名已经与目标一致。