OSNOISE 跟踪器¶
在高 性能计算 (HPC) 的背景下,操作系统噪声(osnoise)指的是由于操作系统内部的活动而导致应用程序受到的干扰。在 Linux 的背景下,NMI、IRQ、SoftIRQ 和任何其他系统线程都可能对系统造成噪声。此外,与硬件相关的工作也可能通过 SMI 等方式产生噪声。
hwlat_detector 是用于识别最复杂噪声源之一的工具:硬件噪声。
简而言之,hwlat_detector 会创建一个线程,该线程会以给定的周期定期运行。在一个周期的开始,该线程会禁用中断并开始采样。在运行期间,hwlatd 线程会循环读取时间。由于中断被禁用,线程、IRQ 和 SoftIRQ 无法干扰 hwlatd 线程。因此,两次不同的时间读取之间任何差距的原因要么在于 NMI,要么在于硬件本身。在该周期的结束,hwlatd 会启用中断并报告读取之间观察到的最大差距。它还会打印 NMI 发生计数器。如果输出没有报告 NMI 执行,用户可以得出结论,硬件是延迟的罪魁祸首。hwlat 通过观察 NMI 的进入和退出来检测 NMI 的执行。
osnoise 跟踪器通过运行类似的循环来利用 hwlat_detector,该循环启用抢占、SoftIRQ 和 IRQ,从而允许在其执行期间出现所有 osnoise 源。使用与 hwlat 相同的方法,osnoise 记录任何干扰源的进入和退出点,从而增加每个 CPU 的干扰计数器。osnoise 跟踪器还为每个干扰源保存一个干扰计数器。每当该工具观察到这些干扰的进入事件时,NMI、IRQ、SoftIRQ 和线程的干扰计数器都会增加。当发生噪声且没有任何来自操作系统级别的干扰时,硬件噪声计数器会增加,指向与硬件相关的噪声。通过这种方式,osnoise 可以解释任何干扰源。在该周期的结束,osnoise 跟踪器会打印所有噪声的总和、最大单噪声、线程可用的 CPU 百分比以及噪声源的计数器。
用法¶
将 ASCII 文本“osnoise”写入跟踪系统的 current_tracer 文件(通常挂载在 /sys/kernel/tracing)。
例如
[root@f32 ~]# cd /sys/kernel/tracing/
[root@f32 tracing]# echo osnoise > current_tracer
可以通过读取跟踪文件来跟踪跟踪
[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)之外,跟踪器会在每个周期的末尾为每个正在运行 osnoise/ 线程的 CPU 打印一条消息。osnoise 特定字段报告
RUNTIME IN US 报告 osnoise 线程保持循环读取时间的时间量(以微秒为单位)。
NOISE IN US 报告 osnoise 跟踪器在关联的运行时期间观察到的噪声总和(以微秒为单位)。
% OF CPU AVAILABLE 报告运行时窗口期间 osnoise 线程可用的 CPU 百分比。
MAX SINGLE NOISE IN US 报告运行时窗口期间观察到的最大单噪声。
干扰计数器显示在运行时窗口期间发生各自的干扰次数。
请注意,上面的示例显示了大量的 HW 噪声样本。原因是此样本是在虚拟机上采集的,并且主机干扰被检测为硬件干扰。
跟踪器配置¶
跟踪器在 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() 读取之间被视为噪声的最小增量,以微秒为单位。当设置为 0 时,将使用默认值,该值当前为 1 微秒。
osnoise/options:一组可以启用(通过将选项名称写入文件)或禁用(通过写入带有“NO_”前缀的选项名称)的开/关选项。例如,写入 NO_OSNOISE_WORKLOAD 会禁用 OSNOISE_WORKLOAD 选项。特殊的 DEAFAULTS 选项会将所有选项重置为默认值。
跟踪器选项¶
osnoise/options 文件公开了一组 osnoise 跟踪器的开/关配置选项。这些选项是
DEFAULTS:将选项重置为默认值。
OSNOISE_WORKLOAD:不调度 osnoise 工作负载(请参阅下面的专用部分)。
PANIC_ON_STOP:如果跟踪器停止,则调用
panic()
。此选项用于捕获 vmcore。OSNOISE_PREEMPT_DISABLE:在运行 osnoise 工作负载时禁用抢占,仅允许 IRQ 和与硬件相关的噪声。
OSNOISE_IRQ_DISABLE:在运行 osnoise 工作负载时禁用 IRQ,仅允许 NMI 和与硬件相关的噪声,如 hwlat 跟踪器。
其他跟踪¶
除了跟踪器之外,还添加了一组跟踪点,以方便识别 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 执行后运行的迁移线程。第一个事件不是噪声的一部分,因为它发生在 1 毫秒之前。
值得注意的是,跟踪点中报告的持续时间之和小于 sample_threshold 中报告的 8 微秒。原因在于任何干扰执行之前和之后发生的入口和出口代码的开销。这证明了双重方法的合理性:测量线程和跟踪。
在没有工作负载的情况下运行 osnoise 跟踪器¶
通过启用设置了 NO_OSNOISE_WORKLOAD 选项的 osnoise 跟踪器,osnoise:跟踪点可用于测量任何类型的 Linux 任务的执行时间,不受其他任务的干扰。