sched discussion
[GIT pull] core/entry for v7.3-rc1
LLM 分析
core/entry / timers/cleanups 等:v7.3-rc1 多分支合入与 ARM get_cycles() 启动挂死修复
系列概况
- 标题:10 个
[GIT pull] <branch> for v7.3-rc1合入请求 + 一组 bugfix 讨论 - 作者:Thomas Gleixner 主送 Linus;后续 reply 由 Nathan Chancellor、Ingo Molnar 接力
- 版本:v7.3-rc1 合并窗口,分支名形如
core-entry-2026-08-17、timers-cleanups-2026-08-17 - 规模:27 封邮件 = 10 封人工 pull request + 13 封 pr-tracker-bot 自动回执 + 4 封人工讨论
- 修改文件:
Documentation/admin-guide/sysctl/kernel.rst、Documentation/core-api/entry.rst、tools/testing/selftests/rseq/、kernel/futex/core.c、kernel/irq/irqdesc.c、drivers/irqchip/、include/linux/{cpuhotplug,sched,smp}.h、include/linux/hrtimer.h、arch/arm/vdso/、arch/arm/include/asm/{timex,delay}.h、drivers/clocksource/等 - 代码统计:每个 PR diffstat 都很小(个位数文件、个位数 +/-),整体是一次常规合并窗口
- Message-ID:
178696575118.1270771.17154447195623102039.tglx@fw13(首封 core/entry pull) - 完整性:完整,含 pull request、merge 通告、bisect、fix、upstream 全流程
补丁目的
Thomas Gleixner 在 v7.3-rc1 合并窗口向 Linus 推送 tip/tip.git 十个分支:core/entry、core/rseq、irq/core、irq/drivers、locking/futex、smp/core、timers/cleanups、timers/clocksource、timers/core、timers/vdso,覆盖文档、SMP/entry/RSEQ、futex selftest、MSI、clocksource、hrtimer API 简化、arm vDSO 32-bit compat 等。
线程真正有技术讨论价值的是后半段:timers/cleanups 里的 calibrate: Rework delay timer calibration(dfc256dac54c)把 read_current_timer() 改名为 delay_read_timer() 并把返回类型从 int 改成 bool,但 ARM timex.h 里的 get_cycles() 宏三元方向没同步翻转,ARM early boot 直接挂死。Nathan Chancellor bisect 出该 commit,Thomas 认账并要求补正式 patch,最终 Ingo 在主线通告修复已合入。
旧流程的问题
旧 read_current_timer() 返回 int:0 表示成功、负值表示失败:
int read_current_timer(unsigned long *timer_val)
{
if (!delay_timer)
return -ENXIO;
*timer_val = delay_timer->read_current_timer();
return 0;
}
EXPORT_SYMBOL_GPL(read_current_timer);
ARM timex.h 里使用(语义:成功拿到值就返回值,否则返回 0):
typedef unsigned long cycles_t;
#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
这里的语义其实从一开始就和"成功=0"约定相悖——按旧 API 应该是"失败 ? 0 : c",但当年就是这么写,且 random_get_entropy() 走 fallback 兜底,ARM 路径没暴露。
新流程
delay_read_timer() 改用 bool,true=成功 / false=失败。Nathan 把三元方向翻过来:
bool delay_read_timer(unsigned long *timer_val)
{
if (!delay_timer)
return false;
*timer_val = delay_timer->read_current_timer();
return true;
}
EXPORT_SYMBOL_GPL(delay_read_timer);
ARM timex.h 改为:
// Temporary workaround until timex.h is cleaned up
bool delay_read_timer(unsigned long *t);
#define get_cycles() ({ cycles_t c; delay_read_timer(&c) ? c : 0; })
#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
关键点:get_cycles() 语义变干净——成功返回真值、失败返回 0,让 random_get_entropy() 在 fallback 路径上正确生效。Ingo Molnar 最后一封邮件通告:"this fix is now upstream."
Patch 概览
- 本帖本身没有 patch 系列,只有 pull request。
- 实质 patch 是 Nathan 的 "fix arm get_cycles() in light of delay_read_timer()",1 个 hunk,单文件
arch/arm/include/asm/timex.h,并带Fixes:tag 指向dfc256dac54c。
关键实现
- tip/tip.git 多分支 pull:每个 PR 都是
git pull风格请求,pr-tracker-bot 在 ~36 小时后自动确认合入torvalds/linux.git。 timers/cleanups:把read_current_timer()重写为delay_read_timer()(bool),新增EXPORT_SYMBOL_GPL(delay_read_timer),新增ARCH_HAS_DELAY_TIMERKconfig 基础设施。timers/core:删除hrtimer_callback_running()、hrtimer_update_function()等冗余 inline,合并掉linux/hrtimer_defs.h。timers/vdso:把arch/arm/vdso/vgettimeofday.c里__vdso_clock_gettime64/__vdso_clock_getres放进#ifdef CONFIG_COMPAT_32BIT_TIME,保留 32-bit 时间 ABI 入口。irq/core:清理kstat_irqs_cpu(),移除多余的desc->kstat_irqs判空,统一走irq_desc_kstat_cpu()helper。irq/drivers:删除IMGPDC_IRQ整个 Kconfig/Makefile 节点;realtek,rtl-intcDT binding 把#interrupt-cells扩成 enum [1,2];irq-gic-its-msi-parent加MSI_FLAG_PCI_MSIX_ALLOC_DYN。core/entry:sysctl 新增kernel.syscall_user_dispatch,文档同步。core/rseq:selftest.gitignore增补legacy_check/check_optimized,顺手修accomodate->accommodate拼写。smp/core:新增struct task_ipi_mask及smp_task_ipi_mask_alloc/free,在CONFIG_SMP && CONFIG_PREEMPTION下启用。
+-------+ pull request +-----------+ merge +-----------+
| tglx | --------------> | tip/tip.* | ---------> | torvalds/ |
+-------+ +-----------+ +-----------+
|
| pr-tracker-bot auto ack
v
+-----------+
| merged |
+-----------+
timers/cleanups trigger chain:
read_current_timer() int --(dfc256dac54c)--> delay_read_timer() bool
| |
| 0=ok / !=0=fail | true=ok / false=fail
+----------------------+---------------------+
|
v
arch/arm/include/asm/timex.h
#define get_cycles() ... delay_read_timer(&c) ? 0 : c;
|
v
semantic inverted -> always returns 0
|
v
random_get_entropy() sees no real cycles
|
v
ARM early boot hang
|
v
Nathan Chancellor bisect -> flip ternary direction
(delay_read_timer(&c) ? c : 0)
|
v
Ingo Molnar: upstreamed
类比
把 read_current_timer() 想象成便利店收银台的"找零"操作:旧 API 用 int,0 表示"零钱已找到",非零是错误码;新 delay_read_timer() 用 bool,true 表示"拿到零钱",false 表示"没拿到"。店铺(timers/cleanups)改了招牌语义,但 ARM 前台的店员(timex.h 里的宏)还按老招牌读——"拿到(true)就把零钱扔掉、给顾客 0 元;没拿到(false)才把钱递出去"。于是顾客(early boot 需要的随机熵)永远只拿到 0 元,队伍越排越长,ARM 启动看起来就是"挂死"。Nathan Chancellor 把店员手里的牌翻过来——拿到就给钱、没拿到才给 0——队伍立刻恢复正常。
Highlight:风险与注意点
- 符号重命名 + 类型变更双变更:旧的
EXPORT_SYMBOL_GPL(read_current_timer)被删除,任何 out-of-tree 驱动或 selftest 仍引用旧符号会链接期undefined reference。 - 编译器不会告警:
get_cycles()是宏,? :方向错了不会触发 warning,只有 ARM 大量虚拟配置启动测试才能暴露。 - bisect 易踩坑:v7.3-rc1 一次性合入 10 个 tip 分支,bisect 停在 tip 树 SHA 时可能跨越多个分支,需要按
Fixes:tag 锚定到dfc256dac54c而不是按 PR 标题猜。 timers/core同步砍 API:hrtimer_callback_running()/hrtimer_update_function()直接删除,外部用户(含 staging 驱动)需要 follow-up 迁移,否则编不过。- vDSO 32-bit 时间 ABI 改动:
arch/arm/vdso/vgettimeofday.c在#ifdef CONFIG_COMPAT_32BIT_TIME内重新放置,对CONFIG_COMPAT_32BIT_TIME=n构建要做 sanity check。
版本变化
本帖只有单一时间线,无 vN -> vN+1 演进;唯一记录的是 Nathan 的 fix 在 v1-1 一个版本内就被 Ingo 合入主线。
一句话总结
这是 v7.3-rc1 合并窗口一组常规 tip 分支合入,主线技术看点只有 timers/cleanups 把 read_current_timer() 改成 bool delay_read_timer() 后 ARM get_cycles() 三元方向没同步翻转,导致 early boot 挂死;Nathan bisect 后 Thomas 认账、Ingo 上线,是一次教科书级的"重命名 + 返回类型变化"漏改案例。