OSNOISE Tracer¶
在高性能计算(HPC)的上下文中,操作系统噪声(osnoise)指的是应用程序由于操作系统内部的活动而受到的干扰。在 Linux 的上下文中,NMIs、IRQs、SoftIRQs 以及任何其他系统线程都可能导致系统噪声。此外,与硬件相关的工作也可能通过 SMI 等方式造成噪声。
hwlat_detector 是用于识别最复杂的噪声源之一:硬件噪声 的工具。
简而言之,hwlat_detector 创建一个线程,该线程以给定的周期定期运行。在一个周期开始时,该线程禁用中断并开始采样。在运行期间,hwlatd 线程在一个循环中读取时间。由于中断被禁用,线程、IRQs 和 SoftIRQs 无法干扰 hwlatd 线程。因此,两次不同的时间读取之间的任何差距都源于 NMI 或硬件本身。在该周期结束时,hwlatd 启用中断并报告观察到的最大读取间隔。它还打印一个 NMI 发生计数器。如果输出未报告 NMI 执行,则用户可以得出结论,硬件是导致延迟的原因。 hwlat 通过观察 NMI 的进入和退出来检测 NMI 执行。
osnoise tracer 通过运行一个类似的循环来利用 hwlat_detector,该循环启用了抢占、SoftIRQs 和 IRQs,从而允许在其执行期间存在所有 osnoise 源。使用与 hwlat 相同的方法,osnoise 记录任何干扰源的进入和退出点,从而增加每个 CPU 的干扰计数器。 osnoise tracer 还为每个干扰源保存一个干扰计数器。每当该工具观察到这些干扰的进入事件时,NMI、IRQs、SoftIRQs 和线程的干扰计数器就会增加。如果发生噪声而没有来自操作系统级别的任何干扰,则硬件噪声计数器会增加,指向与硬件相关的噪声。通过这种方式,osnoise 可以记录任何干扰源。在该周期结束时,osnoise tracer 打印所有噪声的总和、最大单一噪声、线程可用的 CPU 百分比以及噪声源的计数器。
用法¶
将 ASCII 文本 “osnoise” 写入跟踪系统的 current_tracer 文件中(通常挂载在 /sys/kernel/tracing)。
例如
[root@f32 ~]# cd /sys/kernel/tracing/
[root@f32 tracing]# echo osnoise > current_tracer
可以通过读取 trace 文件来跟踪
[root@f32 tracing]# cat trace
# tracer: osnoise
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth MAX
# || / SINGLE Interference counters:
# |||| RUNTIME NOISE % OF CPU NOISE +-----------------------------+
# TASK-PID CPU# |||| TIMESTAMP IN US IN US AVAILABLE IN US HW NMI IRQ SIRQ THREAD
# | | | |||| | | | | | | | | | |
<...>-859 [000] .... 81.637220: 1000000 190 99.98100 9 18 0 1007 18 1
<...>-860 [001] .... 81.638154: 1000000 656 99.93440 74 23 0 1006 16 3
<...>-861 [002] .... 81.638193: 1000000 5675 99.43250 202 6 0 1013 25 21
<...>-862 [003] .... 81.638242: 1000000 125 99.98750 45 1 0 1011 23 0
<...>-863 [004] .... 81.638260: 1000000 1721 99.82790 168 7 0 1002 49 41
<...>-864 [005] .... 81.638286: 1000000 263 99.97370 57 6 0 1006 26 2
<...>-865 [006] .... 81.638302: 1000000 109 99.98910 21 3 0 1006 18 1
<...>-866 [007] .... 81.638326: 1000000 7816 99.21840 107 8 0 1016 39 19
除了常规跟踪字段(从 TASK-PID 到 TIMESTAMP)之外,tracer 还在每个周期结束时为每个运行 osnoise/ 线程的 CPU 打印一条消息。 osnoise 特定字段报告
RUNTIME IN US 报告 osnoise 线程保持循环读取时间的时间量(以微秒为单位)。
NOISE IN US 报告 osnoise tracer 在相关运行时观察到的噪声总和(以微秒为单位)。
% OF CPU AVAILABLE 报告在运行时窗口期间 osnoise 线程可用的 CPU 百分比。
MAX SINGLE NOISE IN US 报告在运行时窗口期间观察到的最大单一噪声。
干扰计数器显示在运行时窗口期间发生每个相应干扰的次数。
请注意,上面的示例显示了大量的 HW 噪声样本。原因是此样本是在虚拟机上采集的,并且主机干扰被检测为硬件干扰。
Tracer 配置¶
tracer 在 osnoise 目录中有一组选项,它们是
osnoise/cpus: 将执行 osnoise 线程的 CPU。
osnoise/period_us: osnoise 线程的周期。
osnoise/runtime_us: osnoise 线程将查找噪声的时间。
osnoise/stop_tracing_us: 如果发生高于配置值的单一噪声,则停止系统跟踪。写入 0 会禁用此选项。
osnoise/stop_tracing_total_us: 如果总噪声高于配置值,则停止系统跟踪。写入 0 会禁用此选项。
tracing_threshold: 被视为噪声的两个 time() 读取之间的最小增量,单位为 us。设置为 0 时,将使用默认值,当前为 1 us。
osnoise/options:一组 on/off 选项,可以通过将选项名称写入文件来启用,或者通过将选项名称加上“NO_”前缀来禁用。例如,写入 NO_OSNOISE_WORKLOAD 会禁用 OSNOISE_WORKLOAD 选项。特殊的 DEAFAULTS 选项将所有选项重置为默认值。
Tracer 选项¶
osnoise/options 文件公开了 osnoise tracer 的一组 on/off 配置选项。这些选项是
DEFAULTS:将选项重置为默认值。
OSNOISE_WORKLOAD:不分派 osnoise 工作负载(参见下面的专用部分)。
PANIC_ON_STOP:如果 tracer 停止,则调用
panic()
。此选项用于捕获 vmcore。OSNOISE_PREEMPT_DISABLE:在运行 osnoise 工作负载时禁用抢占,仅允许 IRQ 和硬件相关的噪声。
OSNOISE_IRQ_DISABLE:在运行 osnoise 工作负载时禁用 IRQ,仅允许 NMI 和硬件相关的噪声,例如 hwlat tracer。
其他跟踪¶
除了 tracer 之外,还添加了一组跟踪点,以方便识别 osnoise 源。
osnoise:sample_threshold:在任何时候噪声高于可配置的 tolerance_ns 时打印。
osnoise:nmi_noise:来自 NMI 的噪声,包括持续时间。
osnoise:irq_noise:来自 IRQ 的噪声,包括持续时间。
osnoise:softirq_noise:来自 SoftIRQ 的噪声,包括持续时间。
osnoise:thread_noise:来自线程的噪声,包括持续时间。
请注意,所有值都是净值。 例如,如果在 osnoise 运行时,另一个线程抢占了 osnoise 线程,它将从一开始启动一个 thread_noise 持续时间。 然后,发生一个 IRQ,抢占 thread_noise,启动一个 irq_noise。 当 IRQ 结束其执行时,它将计算其持续时间,并且此持续时间将从 thread_noise 中减去,以避免双重计算 IRQ 执行。 此逻辑对所有噪声源有效。
这是一个使用这些跟踪点的示例
osnoise/8-961 [008] d.h. 5789.857532: irq_noise: local_timer:236 start 5789.857529929 duration 1845 ns
osnoise/8-961 [008] dNh. 5789.858408: irq_noise: local_timer:236 start 5789.858404871 duration 2848 ns
migration/8-54 [008] d... 5789.858413: thread_noise: migration/8:54 start 5789.858409300 duration 3068 ns
osnoise/8-961 [008] .... 5789.858413: sample_threshold: start 5789.858404555 duration 8812 ns interferences 2
在此示例中,在最后一行报告了一个 8 微秒的噪声样本,指向两次干扰。 回溯跟踪,之前的两个条目是关于在计时器 IRQ 执行之后运行的迁移线程。 第一个事件不是噪声的一部分,因为它发生在一毫秒之前。
值得注意的是,跟踪点中报告的持续时间总和小于 sample_threshold 中报告的八微秒。原因是任何干扰执行之前和之后发生的进入和退出代码的开销。 这证明了双重方法:测量线程和跟踪。
在没有工作负载的情况下运行 osnoise tracer¶
通过启用设置了 NO_OSNOISE_WORKLOAD 选项的 osnoise tracer,osnoise: 跟踪点用于测量任何类型的 Linux 任务的执行时间,而不会受到其他任务的干扰。