原文:How PREEMPT_RT works

1. PREEMPT_RT 是如何工作的?

PREEMPT_RT 是如何实现其目标的?为何采用这种工作方式?这是刻意设计的结果,还是偶然演变而成的?

若有人认为内核开发者是一群混乱的家伙,一切运作都纯属巧合,那他们会大失所望。PREEMPT_RT 并非随机产物——它是在清晰愿景和周密规划下构建的。

由道格拉斯·尼豪斯教授领导的 KURT 项目(堪萨斯大学实时系统)率先探索如何将通用操作系统转化为实时系统。其成果 KURT 2.0 基于 Linux 2.2.5 构建,成为如今 PREEMPT_RT 的蓝图。

关键设计理念之一是将中断处理程序作为线程运行——这项技术如今被称为线程化中断。另一项基础性构想是将处理底层操作(如中断进入代码)的核心内核逻辑,与外围任务(如编程磁盘控制器)分离。

这种分离引入了额外的锁定机制需求。核心内核使用 raw_spinlock_t,该机制同时禁用了调度和中断抢占。相比之下,spinlock_t 演变为如今所谓的睡眠自旋锁。其目标是尽可能让更多代码保持在调度器的控制之下,使其可被抢占。

该设计允许调度器在必要时中断当前上下文,切换至实时工作负载。由于中断处理程序采用线程化设计并使用 spinlock_t,它们同样可被抢占。

基于上述设计,最终在 Linux v2.6.16 版本 [0] 上实现了可运行的原型。随后在 v2.6.34 版本中,内核引入了名为“per-CPU 变量”的新特性。用户空间中与其功能最接近的是线程局部存储(TLS)

Per-CPU 变量的核心思想是:变量(甚至整个结构体)可绑定至特定 CPU,在该 CPU 上运行的代码可无锁访问。但前提访问代码不会被迁移至其他 CPU,也不会被可能访问相同数据的其他任务抢占。为确保此特性,进程上下文中访问 per-CPU 数据时必须禁用抢占机制。

禁用抢占后,代码既无法迁移至其他 CPU,也无法被同一 CPU 上的其他任务抢占。问题解决。

此假设同样适用于 PREEMPT_RT,但可能引发复杂情况。若 per-CPU 段代码冗长或包含大量循环,调度器将无法抢占当前上下文,从而干扰实时工作负载。

此外,per-CPU 代码必须避免使用任何依赖睡眠锁(如 spinlock_t)的函数,因为睡眠锁需要调度器解决竞争条件。这将违反 per-CPU 数据访问的不可抢占性要求。

部分代码段虽经重写未影响 PREEMPT_RT,但此方案无法满足所有 per-CPU 数据用户的需求。亟需一种既遵循原始设计蓝图又能应对当前挑战的新方案。

由此催生了 local_lock_t 的诞生,又一种锁定原语应运而生。虽然它解决了当务之急,却也扩大了开发者可选的锁类型池。

随着锁类型日益复杂,加之其在 PREEMPT_RT 模式下的行为存在不确定性,亟需建立清晰的文档体系。这项工作对现有锁原语进行了分类,并阐明了在启用 PREEMPT_RT 时其语义的变化机制。

这无疑帮助开发者理解了内核中使用的锁定机制,以及PREEMPT_RT如何利用这些机制实现抢占性。但仅此而已吗?最初的设计蓝图呢?

该蓝图可概括为:“所有控制权交由调度器”。关于 PREEMPT_RT 运作方式背后的若干更广泛设计原则,现已整理成文并归纳总结。

1.1 这会影响我的驱动程序或子系统吗?

简短回答:不应该。大部分影响由内核的通用调试基础设施处理。当检测到规则违规时,诸如 LOCKDEP 之类的工具或“在原子操作段内休眠”之类的警告会发出响亮的提示信息。

然而,将更多控制权移至线程上下文可能带来新的挑战。例如,若用户线程长期以系统最高优先级运行,可能阻塞内核线程执行。这会破坏中断处理程序定时器,因为二者均在 PREEMPT_RT 模式以线程形式运行

若应用程序对永不满足的条件进行忙等待,情况将更为棘手 —— 因为它正在阻塞本应满足该条件的组件(如线程化中断)。部分行为变化及其与非实时内核的差异已在文献中记录总结。

并非所有架构都支持 PREEMPT_RT。x86 等架构自该技术早期便参与发展。而另一些架构(如 RISC-V)高度依赖通用内核基础设施,使得 PREEMPT_RT 支持几乎无需额外投入 —— 它们在 PREEMPT_RT 列车抵达主站之前就已顺利登车。

对于计划将 PREEMPT_RT 引入未支持架构的开发者,存在一份关键步骤清单,可确保实现无缝集成。

1.2 最终说明

PREEMPT_RT 并非混乱中诞生的补丁 —— 它是实现 Linux 真正实时能力的长期愿景的结晶。从其根源可追溯至 KURT 项目,到新引入概念背后的问题解决过程,每一步都经过深思熟虑且具有技术基础。

为确保 PREEMPT_RT 持续发挥其初始设想的功能,其核心理念已形成详尽文档以便查阅。期待这能激励更多开发者探索其潜力,并在自身系统中考虑采用该方案。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐