3、PREEMPT_RT补丁简介:发展历史、主线演进与核心关系

聊实时Linux,绕不开PREEMPT_RT。这个补丁集,说白了就是让Linux内核具备硬实时能力的关键。我最早接触它是在2012年,当时一个工业控制项目要求响应延迟必须控制在100微秒以内,标准内核根本做不到。嗯,那时候我就开始深入研究PREEMPT_RT了。

3.1 PREEMPT_RT的发展历史

PREEMPT_RT的故事,得从2004年说起。当时Ingo Molnar(对,就是那个维护调度器的牛人)发起了这个项目。他的目标很明确:让Linux能跑在硬实时场景下。

我简单梳理一下关键时间节点:

时间 里程碑 我的评价
2004年 Ingo Molnar发布首个PREEMPT_RT补丁 那时候补丁还很小,改动集中在中断线程化
2005-2007年 逐步加入自旋锁可抢占、高精度定时器 我记得当时社区争议很大,很多人觉得没必要
2009年 Thomas Gleixner接手维护 这位老兄把代码质量提升了一个档次
2015年 开始大规模主线合入 我参与的一个项目正好赶上这波,爽
2023年 PREEMPT_RT接近完全主线化 现在基本只剩少量核心补丁还在维护

为什么会拖这么久?说白了,实时性改动会触及内核最底层的同步机制。你想想看,把自旋锁改成可抢占的,这相当于把整个内核的并发模型重写了一遍。我在项目中遇到过,光是测试回归就跑了三个月。

3.2 主线内核的实时演进

主线内核这些年,其实一直在吸收PREEMPT_RT的成果。我把它分成三个阶段:

阶段一:PREEMPT_NONE → PREEMPT_VOLUNTARY → PREEMPT

早期内核只有PREEMPT_NONE,也就是完全不抢占。后来加了PREEMPT_VOLUNTARY,在特定点主动让出CPU。再到PREEMPT,允许内核态被抢占。嗯,这三个选项现在还在,但已经不够用了。

阶段二:PREEMPT_RT补丁的逐步合入

从4.x内核开始,大量PREEMPT_RT特性被合入主线:

  • 中断线程化:把硬中断变成内核线程,降低中断延迟抖动
  • 高精度定时器:hrtimer,精度从jiffy级别提升到纳秒级
  • 可抢占自旋锁:spin_lock变成可被抢占的,减少优先级反转
  • RCU改进:让RCU在实时场景下更可预测

核心变化:主线内核从"尽力而为"的调度,变成了"确定性优先"的调度。这个转变花了将近20年。

阶段三:PREEMPT_RT成为内核选项

到了5.x内核,你可以在内核配置里直接选PREEMPT_RT_FULL。虽然还不是默认选项,但已经不需要打补丁了。我建议新手直接选这个选项测试,省去很多麻烦。

3.3 PREEMPT_RT与主线内核的关系

这个问题经常有人问。我直接说结论:PREEMPT_RT是主线内核的超集

具体来说:

  • 主线内核提供基础实时能力(PREEMPT、PREEMPT_VOLUNTARY)
  • PREEMPT_RT在主线基础上增加硬实时特性
  • 大部分PREEMPT_RT代码最终会合入主线
  • 但总有一些核心补丁留在主线外(比如完全可抢占的slub分配器)

我的经验:如果你只需要软实时(延迟1ms以内),主线内核的PREEMPT就够用了。但如果你需要硬实时(延迟100us以内),必须上PREEMPT_RT。我曾经在一个机器人项目中试过只用主线PREEMPT,结果电机控制直接抖成筛子。

这里我画了一张图,帮你理清关系:

主线内核 (Mainline Kernel) PREEMPT_NONE | PREEMPT_VOLUNTARY | PREEMPT 基础调度、中断处理、定时器、同步机制 延迟范围:1ms ~ 10ms(非确定性) PREEMPT_RT 补丁集 中断线程化 | 可抢占自旋锁 | 高精度定时器 优先级继承 | RCU改进 | 实时slub分配器 延迟范围:10us ~ 100us(确定性) 已合入主线(约90%) 仍在外围维护(约10%) 图:PREEMPT_RT与主线内核的关系架构

注意:不要以为选了PREEMPT_RT就万事大吉。我曾经在一个项目里,明明打了PREEMPT_RT补丁,延迟还是飙到500us。查了半天,发现是某个驱动在中断上下文里调用了kmalloc。嗯,驱动代码也得跟着改。

3.4 我的实战建议

如果你刚开始接触PREEMPT_RT,我建议你:

  1. 先跑主线内核的PREEMPT,看看延迟能不能接受
  2. 如果不行,再上PREEMPT_RT,但要做好驱动适配的准备
  3. 用cyclictest测延迟,这是最直观的工具
  4. 关注内核版本,5.10以上对PREEMPT_RT支持更好

我记得有一次,一个客户非要在3.10内核上打PREEMPT_RT补丁。我劝了半天没用,结果折腾了两周,各种冲突。最后换了4.19内核,一天搞定。所以,选对内核版本很重要。

好了,PREEMPT_RT的基本情况就是这样。下一节我们聊聊怎么实际打补丁、配置内核,那才是真正动手的时候。


公众号:蓝海资料掘金营,微信deep3321