RT-Patch 学习 - plus studio - StudyingLover

2024-08-13 11:22:41 浏览数 (2)

RT 是什么

在标准的 Linux 内核中,内核不是完全可抢占的(not fully preemptible)。虽然 Linux 内核支持一些程度的抢占(如在用户空间任务之间的抢占),但在内核态执行关键代码(如持有锁时),内核通常是不可抢占的。这意味着在某些情况下,特别是在处理复杂内核任务时,高优先级的任务可能不得不等待较长时间,直到当前的内核任务完成。

内核抢占指的是在操作系统内核中,当一个高优先级任务需要运行时,低优先级任务可以被暂停(抢占),高优先级任务立即获取 CPU 的控制权。抢占的程度直接影响操作系统响应外部事件的速度。

RT-Preempt 补丁是为 Linux 内核设计的,它将标准的 Linux 内核改造成一个几乎完全可抢占的内核。补丁通过修改内核代码路径,减少或消除内核中的不可抢占部分,使得内核任务可以在更多场景下被抢占。具体来说,RT-Preempt 补丁对内核中的锁机制进行了调整,将大多数“禁用抢占”的区域变成可以被抢占的区域,使得高优先级的任务可以在任何时刻获取 CPU 的控制权。

在一个完全可抢占的内核(例如应用了 RT-Preempt 补丁的 Linux 内核)中,即使内核态正在运行某个任务,只要有一个高优先级的任务准备好执行,操作系统调度器可以暂停当前的内核态任务,切换到高优先级的任务。

普通 linux RT 改进

想要实现 RTLinux 有两种方法

  1. 加一个内核:通过在 Linux 内核与硬件中断之间增加一个可抢先的实时内核,把标准的 Linux 内核作为该实时内核的一个优先级。它可以被实时进程抢断,正常的 Linux 进程仍可以在 Linux 内核上运行,这样既可以使用标准分时操作系统即 Linux 的各种服务,又能提供低延时的实时环境。RTLinux 是采用双内核法改造 Linux 实时性的典型代表。
  2. 打 patch:通过打补丁的方式,对内核的进程调度、中断服务程 序等代码进行修改与优化,提高系统的实时性能

我们可以通过应用 RT-Preempt 补丁,将标准的 Linux 内核转换为一个完全可抢占的内核。LinuxWiki 地址

自内核版本 v2.6.11 以来,每个主线 Linux 内核的长期稳定版本都提供 PREEMPT_RT 补丁。大多数 Linux 内核的长期稳定版本都有偶数子版本号。

RT 技术基础

必须抢占当前正在运行的低优先级任务,以便让实时关键任务运行。抢占取决于任务的调度策略规则。实时系统的另一个重要方面是保证实时任务独占使用某些资源。

中断线程化

Wiki 地址

在标准 Linux 内核中,中断服务例程(ISR)是在硬中断上下文中执行的。在这个上下文中,硬件中断被禁用。这意味着在处理 ISR 的过程中,系统不会响应其他硬件中断,直到当前的中断处理完。硬件中断被禁用的同时,也意味着内核抢占和软中断(soft interrupts)也被禁用。软中断是内核中较低优先级的中断类型,通常用于延迟处理任务。禁用抢占和软中断确保了当前 ISR 的处理不会被其他任务打断,但这也会影响系统的实时性,因为高优先级任务可能无法及时执行。

线程化中断也是 RT-patch Linux 使 Linux 实时化的主要工作,其主要目标是通过将中断处理过程转化为可调度的内核线程,从而提升系统的实时性。

中断处理分为两部分:

  • 上半部: 上半部的处理依然在硬中断上下文中执行,这部分处理的工作量最小,主要处理紧急任务,如清除硬件中断标志或简单的数据读取。
  • 下半部: 下半部的工作则被转化为一个独立的内核线程来执行。这意味着它可以被操作系统调度,具有优先级管理,并且不会阻塞其他更高优先级任务的执行。

优先级继承

Wiki 地址

优先级继承(Priority Inheritance) 是解决 优先级翻转(Priority Inversion) 问题的一种机制

优先级翻转是指在一个多任务操作系统中,低优先级任务因为占用了某种资源,而导致高优先级任务被迫等待,从而让一个中等优先级的任务获得了执行机会,最终造成系统实时性下降的一种现象。

RT-Preempt 补丁通过优先级继承机制有效解决了优先级翻转问题。在这种机制下,当高优先级任务需要被低优先级任务持有的资源时,低优先级任务将继承高优先级任务的优先级,从而能够尽快完成其任务并释放资源。这种机制确保了高优先级任务不会因为等待资源而被中等优先级任务的执行延迟.

下面举一个优先级反转的例子

  1. 低优先级任务 L 先获得了某个共享资源的锁,并开始执行。
  2. 这时,高优先级任务 H 变得可运行,并试图获取 L 已经占用的锁,但由于 L 持有该锁,H 必须等待 L 释放锁。
  3. 然而,另一个 中等优先级任务 M 在 H 等待时也变得可运行,因为 M 的优先级高于 L 且无需该锁,它将抢占 L 的执行时间。这导致 L 无法继续执行,从而无法释放 H 需要的锁。

要解决这个问题,我们需要一个技术叫做优先级继承:

  1. 通过提高持有资源的低优先级任务 L 的优先级来解决优先级翻转的问题。
  2. 当高优先级任务 H 需要一个资源,而该资源正被低优先级任务 L 持有时,L 将继承 H 的优先级。这样 L 就可以优先于中等优先级任务 M 执行,从而尽快释放资源。
  3. 一旦 L 释放了资源,它的优先级将恢复到原来的低优先级,H 重新获得该资源并继续执行。

0 人点赞