Long version :
我想确保我的程序不会被中断,所以我尝试使用实时Linux内核。 我正在使用基于Arch Linux的实时版本(AUR上的linux-rt),并修改了内核配置以选择以下选项:
CONFIG_NO_HZ_FULL=y
CONFIG_NO_HZ_FULL_ALL=y
CONFIG_RCU_NOCB_CPU=y
CONFIG_RCU_NOCB_CPU_ALL=y
然后我重新启动计算机,以以下选项引导此实时内核:
nmi_watchdog=0
rcu_nocbs=1
nohz_full=1
isolcpus=1
我还在BIOS中禁用了以下选项:
C state
intel speed step
turbo mode
VTx
VTd
hyperthreading
我的CPU(i7-6700 3.40GHz)有4个核心(8个逻辑CPU,具有超线程技术)。我可以在/proc/interrupts文件中看到CPU0、CPU1、CPU2、CPU3。
CPU1被“isolcpus”内核参数隔离,我想在这个CPU上禁用本地定时器中断。我以为使用具有CONFIG_NO_HZ_FULL和CPU隔离(isolcpus)的实时内核就足够了,并尝试通过运行以下命令来检查:
cat /proc/interrupts | grep LOC > ~/tmp/log/overload_cpu1
taskset -c 1 ./overload
cat /proc/interrupts | grep LOC >> ~/tmp/log/overload_cpu1
过载过程是:
***overload.c:***
int main()
{
for(int i=0;i<100;++i)
for(int j=0;j<100000000;++j);
}
文件overload_cpu1
包含结果:
LOC: 234328 488 12091 11299 Local timer interrupts
LOC: 239072 651 12215 11323 Local timer interrupts
指的是从本地计时器接收到163个中断而不是0个...
为了比较,我进行了相同的实验,但我改变了我的进程overload
运行的核心(我继续在CPU1上观察中断):
taskset -c 0 : 8 interrupts
taskset -c 1 : 163 interrupts
taskset -c 2 : 7 interrupts
taskset -c 3 : 8 interrupts
我的问题之一是为什么没有0次中断?为什么当我的进程在CPU1上运行时中断次数更多?(我想说如果我的进程是独自运行的,则NO_HZ_FULL将防止中断:“CONFIG_NO_HZ_FULL=y Kconfig选项使内核避免向只有一个可运行任务的CPU发送调度时钟中断” (https://www.kernel.org/doc/Documentation/timers/NO_HZ.txt))。
也许解释在于CPU1上还有其他进程在运行。我使用ps命令检查了一下:
CLS CPUID RTPRIO PRI NI CMD PID
TS 1 - 19 0 [cpuhp/1] 18
FF 1 99 139 - [migration/1] 20
TS 1 - 19 0 [rcuc/1] 21
FF 1 1 41 - [ktimersoftd/1] 22
TS 1 - 19 0 [ksoftirqd/1] 23
TS 1 - 19 0 [kworker/1:0] 24
TS 1 - 39 -20 [kworker/1:0H] 25
FF 1 1 41 - [posixcputmr/1] 28
TS 1 - 19 0 [kworker/1:1] 247
TS 1 - 39 -20 [kworker/1:1H] 501
正如您所看到的,CPU1 上有线程在运行。是否可能禁用这些进程?我想是因为如果不这样做, NO_HZ_FULL 将无法正常工作吧?
TS 类任务并不会打扰我,因为它们在 SCHED_FIFO 中没有优先级,我可以将此策略设置给我的程序。 对于类 FF 且优先级小于 99 的任务也是如此。
然而,您可以看到 migration/1 处于 SCHED_FIFO 并且优先级为 99。 当它们运行时可能会引起中断。这解释了当我的进程在 CPU0、CPU2 和 CPU3 上运行时中断很少(分别为 8、7 和 8 次),但也意味着这些进程并不经常运行,不能解释为什么当我的进程在 CPU1 上运行时有很多中断(163 次)。
我还进行了与我的超载进程的 SCHED_FIFO 相同的实验,结果如下:
taskset -c 0 : 1
taskset -c 1 : 4063
taskset -c 2 : 1
taskset -c 3 : 0
如果我在CPU1上使用SCHED_FIFO策略,那么在这种配置下会有更多的中断,而在其他CPU上则会更少。你知道为什么吗?
RT throttling
(/proc/sys/kernel/sched_rt_period_us)?这可以防止你的 RT 任务完全占用核心并使其他非 RT 任务饿死。理论上,当一个优先级为 99 的 RT 任务正在运行且不自愿放弃核心时,不应该发生 LOC。 - foool