内核线程似乎会干扰完全无滴答模式吗?

Nat*_*mal 5 linux performance kernel thread latency

我正在尝试禁用本地计时器中断以实现低延迟。我在内核配置中启用了完全无滴答模式,并且为相关内核设置了引导参数 nohz_full。

然而,当我通过 /proc/interrupts 查看中断计数时,我看到本地定时器中断每核心每秒计数 1000 次,这意味着完全无滴答不起作用。

无滴答模式文档说,为了使无滴答工作,只有一个正在运行的进程需要在那个核心上。

当我查看顶部时,我在给定的核心(本例中的核心 1)下看到以下内容:

   19 root      RT   0     0    0    0 S  0.0  0.0   0:00.00  1 watchdog/1
   20 root      -2   0     0    0    0 S  0.0  0.0   0:02.15  1 rcuc/1
   21 root      RT   0     0    0    0 S  0.0  0.0   0:00.04  1 migration/1
   22 root      -2   0     0    0    0 S  0.0  0.0   0:00.25  1 ksoftirqd/1
   23 root      RT   0     0    0    0 S  0.0  0.0   0:00.00  1 posixcputmr/1
   24 root      20   0     0    0    0 S  0.0  0.0   0:00.00  1 kworker/1:0
   25 root       0 -20     0    0    0 S  0.0  0.0   0:00.00  1 kworker/1:0H
Run Code Online (Sandbox Code Playgroud)

我知道其中一些是内核线程。这些是我的完全无滴答模式不起作用的原因吗?

max*_*zig 5

使用 eg 激活的完全无滴答模式nohz_full=cpux-cpuy确实只有在每个CPU上只有一个可运行任务时才有效nohz_full

除非在给定的 CPU 上只有一个可运行的任务,否则自适应滴答不会做任何事情,即使在许多其他情况下不需要调度时钟滴答也是如此。

(参见文档/计时器/NO_HZ.txt

因此,如果您nohz_full使用 ps检查CPU,则明确查找可运行任务是有意义的 - 例如:

$ ps -e -L -o cpuid,pid,lwp,state,pri,rtprio,class,wchan:20,comm \
      | awk '$1 == '$mycpunr
Run Code Online (Sandbox Code Playgroud)

(即看状态栏)

这意味着可以在nohz_fullCPU上执行一些附加任务,只要它们不可运行即可。

使用 just nohz_full=,没有什么可以阻止内核在选定的 CPU 上调度用户/内核线程。因此,通常还会隔离这些 CPU 以避免其他线程的任何干扰。例如:

nohz_full=cpux-cpuy isolcpus=cpux-cpuy
Run Code Online (Sandbox Code Playgroud)

(参见Linux 内核参数

使用这些选项,独立nohz_fullCPU上的线程仍然可以被中断,例如通过计时器和 RCU 回调。

因此,如果您想最小化隔离线程的延迟,您需要禁用其他中断源。

您可以检查/proc/timer_list在独立 CPU 上仍处于活动状态的计时器。

可能在独立 CPU 上显示的计时器的常见示例是watchdog_timer_fn和与机器检查异常 (MCE) 功能相关的计时器。

您可以通过进一步的内核选项禁用这些中断,例如:

nowatchdog mce=ignore_ce
Run Code Online (Sandbox Code Playgroud)

查看/proc/interrupts计数器是检查硬件引起的中断的好方法。另一个中断源是软中断,因此还必须检查/proc/softirqs计数器。

例如,为了最大限度地减少隔离 CPU 上与 RCU 相关的中断,可以将 RCU 回调卸载到内核线程,将它们迁移到非隔离 CPU,并通过添加内核选项使隔离 CPU 不必通知回调线程:

rcu_nocb_poll
Run Code Online (Sandbox Code Playgroud)

该选项需要rcu_nocbs=有效,但nohz_full=已经暗示rcu_nocbs=了指定的 CPU。

请注意,您必须明确地将卸载的 RCU 回调线程移动到内务 CPU - 通过明确设置这些线程的 CPU 亲和性。例如金枪鱼(到 CPU 0):

# tuna -U -t 'rcu*' -c 0 -m
Run Code Online (Sandbox Code Playgroud)

内核文档Documentation/kernel-per-CPU-kthreads.txt描述了更多的中断源(又名 OS Jitter),并展示了如何通过在启用跟踪的情况下运行测试负载来定位它们。