以太网 smp_affinity 与 /proc/interrupts 与 /sys/class/net/ethX/device

Mat*_*att 5 linux ethernet interrupts irq

我的目标是为自定义低延迟网络程序配置我们的 CentOS(“免费”RHEL)5.x 服务器。我想尝试将以太网 NIC 中断处理绑定到程​​序运行的同一 CPU(希望提高缓存利用率)。此过程的第一步是确定 NIC 的 IRQ。

以下是一台服务器上 /proc/interrupts 的内容(请注意,为了简洁起见,我删除了 CPU 2 到 14):

           CPU0       CPU1       CPU15
  0:  600299726          0          0    IO-APIC-edge  timer
  1:          3          0          0    IO-APIC-edge  i8042
  8:          1          0          0    IO-APIC-edge  rtc
  9:          0          0          0   IO-APIC-level  acpi
 12:          4          0          0    IO-APIC-edge  i8042
 50:          0          0          0   IO-APIC-level  uhci_hcd:usb6, uhci_hcd:usb8
 58:       6644      25103          0   IO-APIC-level  ioc0
 66:          0          0          0   IO-APIC-level  ata_piix
 74:        221     533830          0   IO-APIC-level  ata_piix
 98:         35          0    2902361       PCI-MSI-X  eth1-0
106:         61         11       3841       PCI-MSI-X  eth1-1
114:         28          0      61452       PCI-MSI-X  eth1-2
122:         24       1586         22       PCI-MSI-X  eth1-3
130:       2912          0        337       PCI-MSI-X  eth1-4
138:         21          0         28       PCI-MSI-X  eth1-5
146:         21          0         56       PCI-MSI-X  eth1-6
154:         34          1          1       PCI-MSI-X  eth1-7
209:         23          0          0   IO-APIC-level  ehci_hcd:usb1
217:          0          0          0   IO-APIC-level  ehci_hcd:usb2, uhci_hcd:usb5, uhci_hcd:usb7
225:          0          0          0   IO-APIC-level  uhci_hcd:usb3
233:          0          0          0   IO-APIC-level  uhci_hcd:usb4
NMI:       7615       2989       2931
LOC:  600328144  600328099  600327086
ERR:          0
MIS:          0
Run Code Online (Sandbox Code Playgroud)

为什么“eth1”有多个“eth1-X”形式的条目?

此外,“/sys/class/net/eth1/device/irq”的内容是“90”。但上面的中断列表中没有90。

假设我只查看“eth1-0”,即 IRQ 98。 /proc/irq/98/smp_affinity 的内容是:

00000000,00000000,00000000,00000000,00000000,00000000,00000000,00008000
Run Code Online (Sandbox Code Playgroud)

这是一列数字,而不仅仅是一个数字。

那么如何设置eth1的smp_affinity呢?

我能找到的在线示例和文档都没有提到类似的情况;它们在 /proc/interrupts 中始终只有一个“ethX”条目;指示的中断与 /sys/class/net/ethX/device/irq 匹配;而/proc/irq/N/smp_affinity中只有一个数字。

FWIW,我要补充一点,这个应用程序对延迟非常敏感。我们禁用 C 状态和处理器频率缩放(因为这些功能会导致太多延迟)。 微秒在这里会产生影响。

编辑:我偶然发现了以下网页 http://www.kernel.org/doc/man-pages/online/pages/man7/cpuset.7.html ,虽然它是关于cpuset的,但它有一个标题为“掩码格式”,我认为它与我在 /proc/irq//smp_affinity 文件中看到的相同。引用:

该格式以十六进制显示每个 32 位字(使用 ASCII 字符“0”-“9”和“a”-“f”);如果需要,单词会用前导零填充。对于长于一个单词的掩码,单词之间使用逗号分隔符。单词以大端顺序显示,最高有效位在前。单词中的十六进制数字也按大端顺序排列。

显示的 32 位字数是显示位掩码的所有位所需的最小数量,具体取决于位掩码的大小。

掩码格式示例:

   00000001                        # just bit 0 set
   40000000,00000000,00000000      # just bit 94 set
   00000001,00000000,00000000      # just bit 64 set
   000000ff,00000000               # bits 32-39 set
   00000000,000E3862               # 1,5,6,11-13,17-19 set
Run Code Online (Sandbox Code Playgroud)

位 0、1、2、4、8、16、32 和 64 设置的掩码显示为:

   00000001,00000001,00010117
Run Code Online (Sandbox Code Playgroud)

第一个“1”代表位 64,第二个“1”代表位 32,第三个代表位 16,第四个代表位 8,第五个代表位 4,“7”代表位 2、1 和 0。

小智 3

为什么“eth1”有多个“eth1-X”形式的条目?

因为有多个 tx/rx 队列。这些队列通常是(本地地址、端口、远程地址、端口)和其他一些内容的散列。假设您的流量源很少,抑制多个队列可能会让您的应用程序更加确定。或者,您可以查找算法并避免使用临时端口,如果这样更容易的话。