openEuler 22.03 LTS 新特性解读 | Preempt_RT_实时系统

来自 Industrial-Control SIG的郭皓

将在 openEuler Developer Day 2022 分享

《openEuler在嵌入式和实时性方面的思考与实践》

欢迎大家观看直播


openEuler 22.03 LTS 版本新增了 Preempt_RT 内核实时补丁,提供软实时特性。该特性由 Industrial-Control SIG 引入,并得到 Kernel SIG、Embedded SIG 和 Yocto SIG 配合与支持,已经被集成到openEuler 22.03 LTS Server 和 openEuler 22.03 LTS Embedded 中。

openEuler 22.03 LTS 新特性解读 | Preempt_RT_unix_02





什么是实时系统

实时系统的典型定义如下:“所谓实时系统,就是系统中计算结果的正确性不仅取决于计算逻辑的正确性,还取决于产生结果的时间。如果完成时间不符合要求,则可以认为系统发生了问题。”也就是说,不管实时应用程序执行的是何种任务,它不仅需要正确执行该任务而且必须及时完成。当前,Preempt_RT 维护者 Thomas Gleixner 给出的“实时”含义是:它和指定的一样快。

Linux 作为一种通用操作系统,随着时间的推移,在功能和时序行为方面一直在发展,以便适合许多其他更具挑战性的场景;尤其是实时系统对 Linux 的实时性改造一直从未停止过。

对 Linux 进行实时性改造,通常可从两个大的方向来着手。一个方向是从 Linux 内核内部开始,直接修改其内核源代码,其典型代表是 Preempt_RT 实时补丁;另一个方向则是从 Linux 内核的外围开始,实现一个与 Linux 内核共存的实时内核,即采用双内核方法,其典型实现为 RTAI/Linux,即现在的 Xenomai。

因为 Xenomai 实时内核与 Linux 内核共存,Xenomai 实时内核小而精巧,能够很好地控制其中的代码质量。Xenomai 实时内核完成了基本的硬件抽象层、任务调度管理和进程间通信管理模块等,能够满足一些硬实时系统的需求。然而,其上的实时应用通常分为实时和非实时两部分来完成 ,实时部分必须使用 Xenomai 提供的特有的 API;非实时部分则可以使用 Linux 提供的系统调用。与 Preempt_RT 实时编程相比,Xenomai 编程实现更为困难,软件移植难度更大。

与双内核机制方案相比,Preempt_RT 实时补丁最大的优势在于它遵循 POSIX 标准,使用该补丁的实时系统应用程序和驱动程序与非实时系统的应用和驱动程序差异很小。因此,在使用该补丁的平台上做相应的开发比双内核机制的方案更容易。另外,该补丁与硬件平台相关性小,可移植性高。由于 Linux 内核过于庞大,有着较多关中断、关抢占代码,加上复杂的内存管理、调度器代码逻辑等众多不确定性因素,使得 Preempt_RT 虽然具有较好的软实时性,但在硬实时性方面有所欠缺。



什么是 Preempt_RT

Preempt_RT 补丁开发始于 2005 年。之后由德国 OSADL 组织赞助,Ingo Molnar、Thomas Gleixner 和 Steven Rostedt 三人共同发起,旨在将 Linux 内核的最大线程切换延迟从无限制的毫秒数降低到数十微秒的有界值。2016 年以后成为 Linux 基金会下属合作项目。目前 Preempt_RT 的赞助者来自 ARM、BMW、CIP、ELISA、Intel、National Instruments、OSADL、RedHat 和 Texas Instruments 等。经过 Preempt_RT 和 Linux 内核工程师在抢占、实时性方面的努力,Linux 内核的抢占延迟降低了几个数量级,使其能够与商业实时操作系统竞争。业界知名的 MontaVista Linux、WindRiver Linux、TimeSys Linux 都有 RT 补丁的身影。像 RTJVM、RTKVM、RTDocker、RTAndroid 等曾经出现过的 Preempt_RT 衍生用例,响应速度都有着不同程度的提升。

多年来,该补丁的许多部分已被纳入主线 Linux,包括高分辨率计时器(2.6.16)、优先级继承(2.6.18)、可抢占的 RCU(2.6.25)、内核互斥量和线程中断处理程序(2.6.30)、完全 Tickless 机制(3.10)、DL 调度器(EDF 调度算法)(3.14)、实时抢占锁(5.15)。然而,该补丁的核心部分仍然在主线之外。从近几年的 Preempt_RT 补丁来看,当前的主要工作不是开发新功能,而是专注于增量式引入主线和特定架构的支持。

当前 openEuler 22.03 LTS 主线内核版本为 Linux Kernel 5.10,有 180 把锁无法抢占,其中 8 把锁在 RT 补丁中强制修改成无法抢占。在最新的 5.17 内核中,Preempt_RT 补丁大小为 265KB,有 189 把锁仍然无法抢占,RT 补丁不再强制修改锁为无法抢占。



当前 Preempt_RT 主要特性

  • 临界区可抢占
  • 中断处理程序可抢占
  • 关中断代码序列可抢占
  • 带有优先级继承机制的内核自旋锁和信号量
  • 线程化处理 RCU
  • 降低延迟措施


部署方法



二进制部署

二进制部署可以安装 openEuler 22.03 LTS 官方源中 rpm 包,需要 root 权限,命令如下:

# yum install kernel-rt

完成安装后重启设备,在 GRUB 引导界面选择 Preempt_RT 内核​​openEuler (5.10.0-60.18.0.rt62.52.oe2203.aarch64) 22.03 LTS​​即可。启动后查看内核,即完成 openEuler 22.03 LTS Preempt_RT 二进制部署。

# uname -r
5.10.0-60.18.0.rt62.52.oe2203.aarch64



获取源码

openEuler 22.03 LTS ​​kernel-rt​​源码可以直接从官方源获取,查询命令如下:

# yum search kernel-rt
...
kernel-rt.src : Linux Kernel

若源里包含 ​​kernel-rt​​ 源码,则可使用如下方式下载并安装:

# yumdownloader --source kernel-rt.src
# rpm -ivh kernel-rt-5.10.0-60.18.0.rt62.52.oe2203.src.rpm && cd ~/rpmbuild

源码目录树如下:

# tree
.
├── SOURCES
│ ├── cpupower.config
│ ├── cpupower.service
│ ├── extra_certificates
│ ├── kernel.tar.gz
│ ├── mkgrub-menu-aarch64.sh
│ ├── patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch
│ ├── patch-5.10.0-60.10.0-rt62.patch
│ ├── pubring.gpg
│ ├── sign-modules
│ └── x509.genkey
└── SPECS
└── kernel-rt.spec


表1:kernel-rt源码包主要文件

文件

说明

kernel.tar.gz

内核源码

patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch

openeuler_defconfig 文件补丁

patch-5.10.0-60.10.0-rt62.patch

Preempt_RT 补丁

kernel-rt.spec

Preempt_RT 内核 spec 文件



源码部署

源码获取后,复制以下文件到自定义目录:

# ll
total 186M
-rw-r--r--. 1 root root 185M Apr 2 14:27 kernel.tar.gz
-rw-r--r--. 1 root root 4.5K Apr 2 14:27 patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch
-rw-r--r--. 1 root root 773K Apr 2 14:27 patch-5.10.0-60.10.0-rt62.patch

补丁合入步骤如下:

# tar -xzf kernel.tar.gz && cd kernel
# patch -p1 < ../patch-5.10.0-60.10.0-rt62.patch
# patch -p1 < ../patch-5.10.0-60.10.0-rt62_openeuler_defconfig.patch

源码编译安装:

# make openeuler_defconfig && make -j`nproc`
# make modules_install && make install
# grub2-mkconfig -o $GRUB_CONFIG_PATH



嵌入式系统部署方法

嵌入式部署 Preempt_RT 方法参见:

https://openeuler.gitee.io/yocto-meta-openeuler/features/preempt_rt.html



实时性能测试


表2:缩略语

缩略语

英文全名

说明

RT 内核

Realtime kernel

实时内核,本文指 openEuler 22.03 LTS 发布的​​kernel-rt​​内核

非 RT 内核

/

非实时内核,实时内核,本文指 openEuler 22.03 LTS 发布的​​kernel​​内核



测试环境


表3:测试软件环境

版本名称

来源

openEuler 22.03 LTS ​​kernel​​ 内核

openEuler 22.03 LTS 官方源

openEuler 22.03 LTS ​​kernel-rt​​ 内核

openEuler 22.03 LTS 官方源

表4:测试硬件环境

硬件型号

硬件配置信息

备注

飞腾 D2000

CPU:8 核 内存:8GB 存储设备:SSD

台式机

树莓派 4B

CPU:Cortex-A72 * 4 内存:8GB 存储设备:SanDisk Ultra 16GB micro SD

开发板

飞腾 2000

CPU:4 核 内存:16GB 存储设备:SSD

台式机

表5:测试软件

测试软件

功能

软件版本

rt-test(cyclictest)

通过 cyclictest 工具,每项测试 1000 万次,输出平均延迟(Avg)和最大延迟(MAX)

1.00

stress

压力测试工具,用于模拟测试 CPU 负载,内存负载,IO 负载等

1.0.4

iperf3

网络测试工具,用于模拟测试网络负载

3.6

memtester

内存测试工具,用于模拟测试内存负载

4.5.1

shell 脚本

用于轮询测试,测试信息的收集整理



测试结果

基于上述硬件测试环境,在 CPU 隔离、空负载、CPU 负载、内存负载、IO 负载和网卡负载等不同条件下的测试数据:


表6:详细测试结果(单位微秒) openEuler 22.03 LTS 新特性解读 | Preempt_RT_unix_03

「归纳如下:」

  1. 通过表 6 数据可以判断,在五种负载情况下并且 CPU 不隔离,RT 内核比非 RT 内核实时性要强。非 RT 内核与 RT 内核在 CPU 不隔离情况下,五种负载对应峰值的比值如表 7(比值数据越大表明非 RT 内核实时性越差):

表7:非RT内核与RT的内核峰值延迟比值数据表

平台

空负载

CPU 负载

内存负载

IO 负载

网卡负载

飞腾 D2000

22.7

117.1

51.0

184.6

2.9

树莓派 4B

3.6

2.9

4.3

0.8

1.5

飞腾 2000

5.4

4.3

5.3

34.7

10.6

「以上数据表明,RT 内核的峰值延迟普遍要优于非 RT 内核。」

  1. 结合四种设备的峰值延迟来看,CPU 负载对实时性影响一般小于 IO 和内存负载,而网卡负载影响最小。四种设备在两种内核下,CPU、内存、IO 和网卡负载与空负载比值如表 8(比值越小越稳定):

表8:负载与空负载峰值延迟比值表

平台

CPU 负载

内存负载

IO 负载

网卡负载

飞腾 D2000(非 RT 内核)

5.2

43.1

212.8

2.7

树莓派 4B(非 RT 内核)

0.8

2.7

1.0

0.7

飞腾 2000(非 RT 内核)

0.8

18

26.8

1.9

飞腾 D2000(RT 内核)

1.0

19.2

26.2

20.6

树莓派 4B(RT 内核)

0.9

1.2

4.2

1.0

飞腾 2000(RT 内核)

1.0

2.2

4.5

1.7

「表 8 各项数据表明,RT 内核在负载情况下,实时性较为稳定。」

「为确保 Cyclictest 测试的有效性,经过飞腾 2000 平台空载测试 2 天,最大延迟为 58 微秒。」



实时性对系统影响测试



测试环境


表9:测试软件环境

版本名称

来源

openEuler 22.03 LTS ​​kernel​​ 内核

openEuler 22.03 LTS 官方源

openEuler 22.03 LTS ​​kernel-rt​​ 内核

openEuler 22.03 LTS 官方源

表10:硬件测试环境

硬件型号

硬件配置信息

备注

飞腾 D2000

CPU:8 核 内存:16GB 存储设备:SSD

台式机

飞腾 2000/4

CPU:4 核 内存:16GB 存储设备:SSD

台式机

表11:测试工具

测试软件

功能

版本

unixbench

系统的基准测试工具,可用于测试 CPU、内存、磁盘等。测试结果与硬件、系统、开发库、编译器等相关。

5.1.3

lmbench

是一套简易可移植的,符合 ANSI/C 标准为 UNIX/POSIX 而制定的微型测评工具。一般来说,它衡量两个关键特征:反应时间和带宽。Lmbench 旨在使系统开发者深入了解关键操作的基础成本。

3alpha4

rt-test(cyclictest)

通过 cyclictest 工具,每项测试 1000 万次,输出平均延迟(Avg)和最大延迟(MAX)

1.00



测试结果

  • 飞腾 D2000 平台 unixbench 测试结果

使用​​unixbench​​单个任务测试非 RT 内核空负载、RT 内核空负载、RT 内核负载 cyclictest(cyclictest -m -h 100 -q -i100 -t 1 -p 99 -n),三种状态详细测试结果如下(表中“RT/非 RT”、“RT 负载/非 RT”为百分比值,数值越大说明 RT 内核性能越好):

表12:单任务Unixbench测试结果

测试项

非 RT 内核

RT 内核

RT 内核负载

RT/非 RT

RT 负载/非 RT

Dhrystone 2 using register variables

24920250.9

24994936.3

25463306.6

100.30%

102.18%

Double-Precision Whetstone

4043.3

4042.8

4042.9

99.99%

99.99%

Execl Throughput

2700.1

2112.1

2109.6

78.22%

78.13%

File Copy 1024 bufsize 2000 maxblock

437294.1

307416.2

303652.3

70.30%

69.44%

File Copy 256 bufsize 500 maxblocks

122072.4

88889.0

86090.9

72.82%

70.52%

File Copy 4096 bufsize 8000 maxblocks

995255.5

809771.5

774228.3

81.36%

77.79%

Pipe Throughput

612119.9

487314.9

482060.0

79.61%

78.75%

Pipe-based Context Switching

79151.2

65953.5

65399.0

83.33%

82.63%

Process Creation

5098.4

3481.7

3367.9

68.29%

66.06%

Shell Scripts (1 concurrent)

3907.2

3311.8

3264.1

84.76%

83.54%

Shell Scripts (8 concurrent)

1724.2

1199.9

1187.6

69.59%

68.88%

System Call Overhead

478285.9

436596.3

434507.4

91.28%

90.85%

「System Benchmarks Index Score」

「773.4」

「626.4」

「618.5」

「80.99%」

「79.97%」

使用​​unixbench​​多任务测试非 RT 内核空负载、RT 内核空负载、RT 内核负载 cyclictest(cyclictest -m -h 100 -q -i100 -t 1 -p 99 -n),三种状态详细测试结果如下(表中“RT/非 RT”、“RT 负载/非 RT”为百分比值,数值越大说明 RT 内核性能越好):

表13:多任务Unixbench测试结果

测试项

非 RT 内核

RT 内核

RT 内核负载

RT/非 RT

RT 负载/非 RT

Dhrystone 2 using register variables

199461755.8

199159490.6

195978301.9

99.85%

98.25%

Double-Precision Whetstone

32216.4

32308.6

32094.1

100.29%

99.62%

Execl Throughput

14832.9

9786.4

9375.0

65.98%

63.20%

File Copy 1024 bufsize 2000 maxblock

924225.9

107564.5

104520.3

11.64%

11.31%

File Copy 256 bufsize 500 maxblocks

253687.9

27474.4

26157.9

10.83%

10.31%

File Copy 4096 bufsize 8000 maxblocks

2523753.4

415702.5

395431.5

16.47%

15.67%

Pipe Throughput

4848867.9

3771186.3

3822723.4

77.77%

78.84%

Pipe-based Context Switching

657475.9

526984.6

522867.1

80.15%

79.53%

Process Creation

29117.5

11881.7

11580.0

40.81%

39.77%

Shell Scripts (1 concurrent)

17309.7

8265.0

8199.6

47.75%

47.37%

Shell Scripts (8 concurrent)

2308.1

957.1

937.3

41.47%

40.61%

System Call Overhead

2928882.1

2765649.3

2744875.5

94.43%

93.72%

「System Benchmarks Index Score」

「3406.4」

「1525.8」

「1494.4」

「44.79%」

「43.87%」

  • 飞腾 D2000 平台 lmbench 测试结果

    使用​​lmbench​​测试非 RT 内核空负载、RT 内核空负载、RT 内核负载 cyclictest(cyclictest -m -h 100 -q -i100 -t 1 -p 99 -n),三种状态详细,测试十次取平均值,结果如下:

  • 表14:多任务Lmbench测试结果 openEuler 22.03 LTS 新特性解读 | Preempt_RT_linux_04
  • 飞腾 2000 平台测试结果

    飞腾 2000 平台测试结果与飞腾 D2000 平台测试结果相似度较高,具体数据不在此处列出。


测试结论

「Preempt_RT 补丁可以有效提高系统实时性,且在多种负载场景下,实时性表现较为稳定。」

「Preempt_RT 补丁对本地通讯吞吐率有一定影响,主要提现为管道读写、文件拷贝,对系统调用延迟影响大多在 2 微秒以内。」



后续工作

  1. 跟随内核主线发布、维护 Preempt_RT 补丁
  2. 研发实时性性能分析工具
  3. 提升实时性
  4. 提升吞吐率
  5. 引入 RTLA、RTSL 机制等


主要参与者

特别感谢 Kernel SIG 组XieXiuQi、zhengzengkai,Embedded SIG 组wanming-hu,树莓派 SIG 组woqidaideshi,QA SIG 组suhang给予我们的帮助。



姓名

Gitee ID

郭皓

guohaocs2c

马玉昆

kylin-mayukun

张远航

zhangyh1992




微信公众号 - openEuler(openEulercommunity)。