从 fork 到 exit:Linux 调度器全解Linux 6.12.110

系列 A · 场景主线:一个程序的一生

这是全系列的主干。9 篇文章沿着 导读 0.1 的状态机总图,一条箭头一条箭头往下走。每篇都只盯 demo 程序生命中的一个时刻,把这个时刻里调度器做的所有事情讲完,包括通用代码、ARM64 代码和 RT 相关的差异。

状态机总图:本系列的每一篇对应图中的一条箭头
状态机总图:本系列的每一篇对应图中的一条箭头
篇目 demo 此刻在干什么 核心问题 状态
A1 fork:一次调用,两次返回 父进程在 CPU4 上调 fork() 子进程的调度实体怎么初始化?放到哪个 CPU?谁来叫醒那个 CPU?
A2 选核专题:fork / exec / wakeup 三条路 子进程 exec、线程被唤醒 WF_FORK / WF_EXEC / WF_TTWU 选核有什么不同?EAS 何时介入?
A3 第一次上 CPU CPU2 从 WFI 醒来,第一次运行子进程 __schedulecpu_switch_toret_from_forkeret,每一步换了什么?
A4 运行中:tick、PELT 与时间片 worker 死循环计算 vruntime 怎么涨?util 怎么涨?什么时候判定时间片用完?
A5 睡眠:从 set_current_state 到出队 io 线程 usleep 为什么先设状态再检查条件?delayed dequeue 是什么?
A6 唤醒:try_to_wake_up 全流程 定时器到期唤醒 io on_cpu 等待、wake list、IPI、唤醒抢占
A7 抢占:从标记到切换 ctrl 每 1ms 醒来抢占 worker 抢占模型对比、两条抢占路径、延迟拆解
A8 迁移:负载均衡、misfit 与 EAS worker 从小核被搬到大核 谁发起迁移?怎么选目标?迁移时 PELT 怎么带走?
A9 退出:谁来埋葬最后一个栈 子进程 return → exit do_task_dead 之后,栈和 task_struct 由谁释放?

章节

  1. A1 fork:一次调用,两次返回
  2. A3 第一次上 CPU:从 WFI 到 eret