31.2. 调整 IRQ 平衡


在多核主机上,您可以通过确保 Red Hat Enterprise Linux 平衡中断队列(IRQ)来在 CPU 核之间分发中断来提高性能。

31.2.1. 中断和中断处理程序

当网络接口控制器(NIC)接收传入数据时,它使用直接内存访问(DMA)将数据复制到内核缓冲区中。然后,NIC 通过触发一个硬中断来向内核通知此数据。这些中断由中断处理程序处理的,这些处理程序做最少的工作,因为它们已中断了另一个任务,处理程序无法中断自己。硬中断在 CPU 用量方面代价高昂,特别是如果它们使用内核锁。

然后,硬中断处理器会将大多数数据包接收留给软件中断请求(SoftIRQ)进程。内核可以更公平地调度这些进程。

例 31.1. 显示硬件中断

内核将中断数存储在 /proc/interrupts 文件中。要显示特定 NIC (如 enp1s0)的计数,请输入:

# grep -E "CPU|enp1s0" /proc/interrupts
         CPU0     CPU1     CPU2    CPU3    CPU4   CPU5
 105:  141606        0        0       0       0      0  IR-PCI-MSI-edge      enp1s0-rx-0
 106:       0   141091        0       0       0      0  IR-PCI-MSI-edge      enp1s0-rx-1
 107:       2        0   163785       0       0      0  IR-PCI-MSI-edge      enp1s0-rx-2
 108:       3        0        0  194370       0      0  IR-PCI-MSI-edge      enp1s0-rx-3
 109:       0        0        0       0       0      0  IR-PCI-MSI-edge      enp1s0-tx

每个队列在分配给它的第一列中有一个中断向量。当系统引导时,或者当用户载入 NIC 驱动程序模块时,内核会初始化这些向量。每个接收(RX)和传输(TX)队列都会被分配一个唯一的向量,来告知中断处理程序中断来自哪个 NIC 或队列。列代表每个 CPU 核的传入中断数。

31.2.2. 软中断请求

软中断请求(SoftIRQ)清除网络适配器的接收环缓冲。当其他任务不会被中断时,内核调度 SoftIRQ 例程运行。在 Red Hat Enterprise Linux 上,名为 ksoftirqd/cpu-number 的进程运行这些例程,并调用特定于驱动程序的代码函数。

要监控每个 CPU 核的 SoftIRQ 数,请输入:

# watch -n1 'grep -E "CPU|NET_RX|NET_TX" /proc/softirqs'
                    CPU0       CPU1	  CPU2       CPU3	CPU4	   CPU5       CPU6	 CPU7
      NET_TX:	   49672      52610	 28175      97288      12633	  19843      18746     220689
      NET_RX:         96       1615        789         46         31	   1735       1315     470798

命令动态更新输出。按 Ctrl+C 中断输出。

31.2.3. NAPI 轮询

新的 API (NAPI)是处理框架的设备驱动程序数据包的扩展,以提高传入网络数据包的效率。硬中断非常昂贵,因为它们通常会导致上下文在内核空间和用户空间之间来回切换,并且不能中断自己。即使中断合并,中断处理器也会完全独占 CPU 核。使用 NAPI 时,驱动程序可以对每个接收的数据包使用轮询模式,而不是内核发起的硬中断。

在正常操作下,内核会发出一个初始硬中断,后跟软中断请求(SoftIRQ)处理程序,该处理程序使用 NAPI 例程轮询网卡。为防止 SoftIRQ 独占 CPU 核,轮询例程有一个预算来确定 SoftIRQ 可以使用的 CPU 时间。完成 SoftIRQ 轮询例程后,内核会退出例程,并安排它稍后再次运行,以重复从网卡接收数据包的过程。

31.2.4. irqbalance 服务

在具有和没有非统一内存访问(NUMA)架构的系统上,irqbalance 服务根据系统状况有效地在 CPU 核间平衡中断。irqbalance 服务在后台运行,每 10 秒监控一次 CPU 负载。当 CPU 的负载过高时,服务会将中断移到其他 CPU 核。因此,该系统表现良好,并更有效地处理负载。

如果 irqbalance 没有运行,则通常 CPU 核 0 处理大多数中断。即使在中等负载,这个 CPU 核可能会变得很忙碌,试图处理系统中所有硬件的工作负载。因此,中断或基于中断的工作可能会丢失或延迟。这可能导致网络和存储性能较低、数据包丢失和其他潜在问题。

重要

禁用 irqbalance 可能会对网络吞吐量造成负面影响。

在只有一个 CPU 核的系统上,irqbalance 服务没有提供任何好处,并自行退出。

默认情况下,irqbalance 服务在 Red Hat Enterprise Linux 上启用并运行。要重新启用服务(如果您禁用了它),请输入:

# systemctl enable --now irqbalance

其他资源

31.2.5. 增加 SoftIRQ 可在 CPU 上运行的时间

如果 SoftIRQ 没有运行足够长时间,则传入数据的速度可能会超过内核排空缓冲区的速度。因此,网络接口控制器(NIC)缓冲区溢出,数据包丢失。

如果 softirqd 进程无法在一个 NAPI 轮询周期中内检索来自接口的所有数据包,则它是一个表示 SoftIRQ 没有足够 CPU 时间的指示器。在具有快速 NIC(如 10 Gbps 和更快)的主机上,可能会出现这种情况。如果您增加 net.core.netdev_budgetnet.core.netdev_budget_usecs 内核参数的值,您可以控制softirqd在一个轮询周期内处理数据包的时间和数量。

流程

  1. 要确定是否需要调整 net.core.netdev_budget 参数,请显示 /proc/net/softnet_stat 文件中计数:

    # awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t
    221951548  0  0      0  0  0  0  0  0  0  0  0  0
    192058677  0  20380  0  0  0  0  0  0  0  0  0  1
    455324886  0  0      0  0  0  0  0  0  0  0  0  2
    ...

    awk 命令将 /proc/net/softnet_stat 中的值从十六进制转换为十进制格式,并以表格式显示它们。每行表示以核 0 开始的 CPU 核。

    相关的列有:

    • 第一列:收到的总帧数。
    • 第三列:softirqd 进程在一个 NAPI 轮询周期内无法从接口检索所有数据包的次数。
    • 最后一列:CPU 核号。
  2. 如果 /proc/net/softnet_stat 文件的第三列中的计数随着时间而递增,请调整系统:

    1. 显示 net.core.netdev_budget_usecsnet.core.netdev_budget 参数的当前值:

      # sysctl net.core.netdev_budget_usecs net.core.netdev_budget
      net.core.netdev_budget_usecs = 2000
      net.core.netdev_budget = 300

      使用这些设置时,softirqd 进程最多有 2000 微秒来在一个轮询周期内处理最多 300 个来自 NIC 的消息。轮询根据哪个条件最先满足而结束。

    2. 使用以下内容创建 /etc/sysctl.d/10-netdev_budget.conf 文件:

      net.core.netdev_budget = 600
      net.core.netdev_budget_usecs = 4000

      将参数设置为其当前值的两倍。

    3. /etc/sysctl.d/10-netdev_budget.conf 文件中加载设置:

      # sysctl -p /etc/sysctl.d/10-netdev_budget.conf

验证

  • 监控 /proc/net/softnet_stat 文件中的第三列:

    # awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t

    如果值仍然增加,请将 net.core.netdev_budget_usecsnet.core.netdev_budget 设置为更高的值。重复此过程,直到计数不再增加。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.