2. PREEMPT_RT内核概述
PREEMPT_RT 补丁集是 Linux 内核实现硬实时能力的关键技术。本章从补丁历史、内核配置选项以及与主线内核的差异三个维度,帮助学员建立对 PREEMPT_RT 内核的整体认知。
2.1 PREEMPT_RT 补丁历史
PREEMPT_RT 补丁(又称 -rt 补丁)由 Thomas Gleixner、Ingo Molnar 等内核开发者维护,旨在将 Linux 内核改造为支持确定性抢占的实时操作系统。
| 时间 | 里程碑 | 关键贡献 |
|---|---|---|
| 2004 年 | Ingo Molnar 发布首个 -rt 补丁 | 引入实时互斥锁(rt_mutex)和优先级继承 |
| 2005–2009 年 | 社区大规模重构 | 将中断线程化、高精度定时器、RCU 抢占支持等特性逐步合入主线 |
| 2010–2015 年 | 主线内核吸收大量 -rt 特性 | 自旋锁可抢占、mutex 优先级继承、FUTEX 实时化等进入主线 |
| 2019 年 | PREEMPT_RT 主线化启动 | Linus Torvalds 同意将剩余 -rt 补丁逐步合入 Linux 5.x |
| 2021 年 | Linux 5.15 集成 PREEMPT_RT 核心 | PREEMPT_RT 成为主线内核的正式配置选项 |
关键理解: PREEMPT_RT 并非一个独立内核,而是对主线内核的增量补丁集。从 Linux 5.15 开始,核心实时功能已合入主线,但部分调试接口和实验性特性仍需额外补丁。
2.2 内核配置选项
启用 PREEMPT_RT 需要在内核配置中选择合适的抢占模型。以下是与实时抢占相关的核心配置选项:
| 配置选项 | 含义 | 适用场景 |
|---|---|---|
CONFIG_PREEMPT_NONE |
无抢占(服务器模式) | 高吞吐量服务器,对延迟不敏感 |
CONFIG_PREEMPT_VOLUNTARY |
自愿抢占(桌面模式) | 桌面系统,需要一定响应性 |
CONFIG_PREEMPT |
低延迟抢占(嵌入式模式) | 大多数嵌入式 Linux 系统 |
CONFIG_PREEMPT_RT |
完全实时抢占(硬实时模式) | 工业控制、机器人、音频处理等硬实时场景 |
配置命令示例: 使用
make menuconfig 进入内核配置界面,路径为:General setup → Preemption Model → Fully Preemptible Kernel (Real-Time)
除抢占模型外,以下配置选项对 PREEMPT_RT 的行为有直接影响:
- CONFIG_RT_MUTEXES — 启用实时互斥锁,支持优先级继承协议。
- CONFIG_PREEMPT_RCU — 允许 RCU 读侧临界区被抢占,降低 RCU 延迟。
- CONFIG_HIGH_RES_TIMERS — 高精度定时器,提供微秒级定时精度。
- CONFIG_IRQ_FORCED_THREADING — 强制中断线程化,将硬中断处理移至内核线程上下文。
- CONFIG_DEBUG_PREEMPT — 抢占调试选项,检测非法抢占行为。
2.3 与主线内核的差异
PREEMPT_RT 内核与主线内核在抢占粒度、锁机制、中断处理等方面存在显著差异。下表总结了核心区别:
| 特性 | 主线内核(默认) | PREEMPT_RT 内核 |
|---|---|---|
| 抢占粒度 | 仅在明确定义的抢占点可抢占 | 几乎所有内核代码均可抢占(包括 spinlock 临界区) |
| 自旋锁 | 原始自旋锁(忙等待) | 自旋锁被替换为可睡眠的 rt_mutex 基锁 |
| 中断处理 | 硬中断上下文,不可被调度 | 中断线程化,可被高优先级任务抢占 |
| RCU 读侧 | 读侧临界区不可抢占 | 读侧临界区可抢占(PREEMPT_RCU) |
| 优先级继承 | 仅 futex 和 rt_mutex 支持 | 所有锁机制均支持优先级继承 |
| 定时器精度 | 取决于 HZ 配置(通常 1–10ms) | 高精度定时器(微秒级) |
| 调度延迟 | 数十毫秒级 | 可控制在 100 微秒以内 |
重要提示: PREEMPT_RT 内核的确定性提升以吞吐量下降为代价。在启用 PREEMPT_RT 后,系统整体吞吐量可能下降 5%–15%,因此在非实时场景下不建议启用。
2.4 优先级继承在 PREEMPT_RT 中的定位
优先级继承是 PREEMPT_RT 内核实现确定性调度的核心机制之一。在主线内核中,优先级继承仅局限于 futex 和 rt_mutex;而在 PREEMPT_RT 中,所有锁机制(包括被替换的自旋锁)都内置了优先级继承支持。
关键结论: PREEMPT_RT 内核通过将自旋锁替换为 rt_mutex,使得优先级继承协议覆盖了内核中几乎所有的锁竞争场景,从而从根本上消除了优先级反转问题。