2. 时钟中断基础:时钟中断的概念、产生机制与Tick周期
时钟中断是操作系统内核调度系统的“心跳”。没有时钟中断,CFS 调度器就无法周期性地检查当前进程的运行时间、更新 vruntime、判断是否需要抢占。本节从概念出发,逐步拆解时钟中断的硬件产生机制、频率配置及其与调度 Tick 的关系。
2.1 时钟中断的概念
时钟中断(Timer Interrupt)是由硬件定时器按照固定时间间隔向 CPU 发送的中断信号。CPU 收到信号后暂停当前指令流,跳转到中断处理程序(Interrupt Service Routine, ISR)执行内核预定义的逻辑,处理完毕后恢复原进程的执行。
时钟中断在调度系统中的关键职责包括:
- 计时基准:维护系统 jiffies 计数器,提供全局时间参考。
- 进程记账:触发调度器更新当前进程的 vruntime。
- 抢占触发:检查当前进程是否用尽时间片,决定是否需要重新调度。
- 定时器管理:驱动内核定时器(timer_list、hrtimer)的到期处理。
2.2 时钟中断的产生机制
现代 x86 系统中,时钟中断的硬件来源主要有三种:PIT、HPET 和 LAPIC 定时器。它们在不同阶段、不同场景下承担着产生周期性中断的任务。
| 定时器类型 | 全称 | 精度 | 频率范围 | 使用场景 |
|---|---|---|---|---|
| PIT | Programmable Interval Timer | ~1.193 MHz | 18.2 Hz ~ 1.193 MHz | 传统 PC/BIOS 兼容、低精度 Tick |
| HPET | High Precision Event Timer | ≥ 10 MHz | 可配置,通常 10~25 MHz | 高精度定时、替代 PIT |
| LAPIC Timer | Local APIC Timer | 与 CPU 总线频率相关 | 可编程,通常 MHz 级 | 多核 SMP 系统、每 CPU 独立 Tick |
2.2.1 PIT (Programmable Interval Timer)
PIT 是 IBM PC/AT 时代遗留的经典定时器,芯片型号为 Intel 8253/8254。它通过 I/O 端口 0x40~0x43 编程,工作在“方波发生器”或“速率发生器”模式,产生周期性中断请求(IRQ 0)。
- 时钟源:1.1931816 MHz 晶振。
- 分频计数器:16 位递减计数器,最小计数值 2,最大 65535。
- 典型中断频率:18.206 Hz(计数值 65535)或 100 Hz(计数值 11931)。
- 局限性:精度低、单通道、不支持多核独立定时。
clocksource 的备选,当 HPET 或 TSC 不可用时才回退到 PIT。调度 Tick 频率 HZ 的配置与 PIT 的分频值直接相关。
2.2.2 HPET (High Precision Event Timer)
HPET 是 Intel 和 Microsoft 联合制定的高精度定时器标准,旨在替代 PIT 和 RTC 定时器。它提供多个独立的比较器/定时器通道,精度远高于 PIT。
- 时钟源:独立晶振,频率 ≥ 10 MHz(通常 14.31818 MHz 或 25 MHz)。
- 通道数量:至少 3 个(通常 8 个),可独立配置。
- 中断路由:每个通道可路由到不同的 CPU 核心或 I/O APIC。
- 精度优势:支持 1 微秒级别的定时精度,适合高精度定时器(hrtimer)。
2.2.3 LAPIC Timer (Local APIC Timer)
LAPIC 定时器是集成在 CPU 内部 Local APIC 单元中的定时器,每个 CPU 核心拥有独立的 LAPIC 定时器。它在 SMP 系统中扮演核心角色,为每个 CPU 提供独立的 Tick 中断源。
- 时钟源:CPU 总线频率(FSB)或核心时钟分频。
- 工作模式:一次性(One-shot)或周期性(Periodic)。
- 中断向量:通过 LAPIC 的 LVT Timer 寄存器配置,通常分配为 0xEF(Linux 中的 LOC 中断)。
- 优势:每个 CPU 独立、低延迟、不依赖外部芯片组。
2.3 时钟中断频率与 Tick 周期
时钟中断的频率决定了调度器检查进程运行时间的粒度。这个频率在 Linux 内核中由编译常量 HZ 定义,单位是“次/秒”。Tick 周期 = 1 / HZ 秒。
| HZ 值 | Tick 周期 | 典型架构 | 特点 |
|---|---|---|---|
| 100 | 10 ms | ARM、MIPS 嵌入式 | 低功耗、低中断开销 |
| 250 | 4 ms | x86 桌面/服务器 | 平衡调度精度与开销 |
| 300 | 3.33 ms | Android / 移动设备 | 与视频帧率对齐 |
| 1000 | 1 ms | x86 实时/低延迟 | 高精度调度、中断开销大 |
Tick 周期对调度延迟的影响:
- 高 HZ(1000):调度器响应更快,进程抢占延迟更低,适合交互式桌面、实时音频。但中断处理开销增加,CPU 吞吐量略有下降。
- 低 HZ(100):中断开销小,CPU 更多时间用于计算,适合批处理服务器。但进程可能多运行 10 ms 才被抢占,交互响应变差。
2.4 时钟中断处理流程概览
一次完整的时钟中断从硬件触发到调度决策,经历以下关键步骤:
- 硬件触发:定时器(PIT/HPET/LAPIC)计数器归零,向 CPU 发送中断信号。
- 中断向量查找:CPU 根据中断向量号在 IDT(Interrupt Descriptor Table)中找到对应的中断门。
- 上下文保存:CPU 自动保存当前进程的 CS、RIP、RSP、EFLAGS 到内核栈。
- 中断处理函数:调用
do_timer()或tick_handle_periodic(),更新 jiffies、处理定时器。 - 调度器入口:调用
scheduler_tick(),更新当前进程的 vruntime,检查是否需要抢占。 - 中断返回:恢复上下文,若设置了
need_resched标志,则触发进程切换。
scheduler_tick() 开始执行之间的时间,是调度延迟的第一段。这段延迟受中断屏蔽、中断嵌套、缓存缺失等因素影响,是后续章节重点分析的对象。
2.5 本节小结
- 时钟中断是调度系统的硬件驱动源,负责提供周期性检查点。
- PIT 是传统低精度定时器,HPET 提供高精度多通道支持,LAPIC 定时器实现每 CPU 独立 Tick。
- HZ 值决定 Tick 周期,直接影响调度延迟和系统开销。
- 时钟中断处理流程中,
scheduler_tick()是连接中断与 vruntime 更新的关键桥梁。