gpt4 book ai didi

timer - 实时 Linux : disable local timer interrupts

转载 作者:行者123 更新时间:2023-12-04 15:52:00 41 4
gpt4 key购买 nike

TL;博士 :实时使用带有 NO_HZ_FULL 的 Linux 内核我需要隔离一个进程以获得确定性结果,但是/proc/interrupts 告诉我仍然有本地定时器中断(等等)。如何禁用它?

长版:

我想确保我的程序没有被中断,所以我尝试使用实时 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

含义 651-488 = 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 的任务,同样的事情。

但是,您可以看到 SCHED_FIFO 中的 migration/1 和优先级 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 上使用较少,则会有更多中断。你知道为什么吗 ?

最佳答案

问题是完全无滴答的 CPU(又名自适应滴答,配置为 nohz_full=)仍然会收到一些滴答声。

最值得注意的是,调度程序需要一个独立的完整无滴答 CPU 上的计时器,以每秒左右更新一些状态。

这是记录在案的限制(截至 2019 年):

Some process-handling operations still require the occasional scheduling-clock tick. These operations include calculating CPU load, maintaining sched average, computing CFS entity vruntime, computing avenrun, and carrying out load balancing. They are currently accommodated by scheduling-clock tick every second or so. On-going work will eliminate the need even for these infrequent scheduling-clock ticks.



(来源: Documentation/timers/NO_HZ.txt,参见 LWN 文章 (Nearly) full tickless operation in 3.10 来自 2013 年的一些背景)

测量本地定时器中断( /proc/interrupts 中的 LOC 行)的更准确方法是使用 perf .例如:
$ perf stat -a -A -e irq_vectors:local_timer_entry ./my_binary

哪里 my_binary将线程固定到独立的 CPU,这些 CPU 不间断地使用 CPU,而不调用系统调用 - 例如 - 2 分钟。

还有其他本地计时器滴答的其他来源(当只有 1 个可运行任务时)。

例如,VM 统计信息的收集 - 默认情况下每秒钟收集一次。因此,我可以通过设置更高的值来减少我的 LOC 中断,例如:
# sysctl vm.stat_interval=60

另一个来源是定期检查不同 CPU 上的 TSC 是否不漂移 - 您可以使用以下内核选项禁用这些:
tsc=reliable

(仅当您确实知道您的 TSC 不会漂移时才应用此选项。)

您可能会通过使用 ftrace 记录跟踪来找到其他来源。 (当您的测试二进制文件正在运行时)。

因为它出现在评论中:是的,SMI 对内核是完全透明的。它不会显示为 NMI。您只能间接检测 SMI。

关于timer - 实时 Linux : disable local timer interrupts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46077582/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com