我开发了一个 XDP 程序,它根据某些特定规则过滤数据包,然后将它们丢弃(XDP_DROP
)或将它们重定向(xdp_redirect_map
)到另一个接口。该程序仅在四个 CPU 内核上就能够很好地处理 ~11Mpps 的合成负载(这就是我的流量生成器的全部能力)。
现在我已经更改了该程序以用于XDP_TX
在接收数据包的接口上发送数据包,而不是将它们重定向到另一个接口。不幸的是,这个简单的更改导致吞吐量大幅下降,现在几乎无法处理 ~4Mpps。
我不明白,这可能是什么原因或如何进一步调试,这就是我在这里问的原因。
我重现问题的最小测试设置:
- 两台具有直接相互连接的 Intel x520 SFP+ NIC 的机器,两个 NIC 都配置为具有与机器具有 CPU 内核一样多的“组合”队列。
- 机器 1使用来自 linux 源的示例应用程序运行 pktgen:
./pktgen_sample05_flow_per_thread.sh -i ens3 -s 64 -d 1.2.3.4 -t 4 -c 0 -v -m MACHINE2_MAC
(4 个线程,因为这是导致生成的最高 Mpps 的配置,即使机器有超过 4 个内核) - 机器 2运行一个简单的程序来丢弃(或反射)所有数据包并计算 pps。在该程序中,我已将
XDP_DROP
返回码替换为XDP_TX
. -我是否在反映数据包之前交换 src/dest mac 地址并不会导致吞吐量差异,所以我把它留在这里。
使用 运行程序时,机器 2XDP_DROP
上的 4 个内核稍微加载了线程,同时下降了约 11Mps。考虑到由于 NIC 中的散列是如何工作的,pktgen 发出 4 个不同的数据包,这些数据包仅填充 4 个 rx 队列,因此仅加载 4 个内核是有道理的。ksoftirqd
但是当使用 运行程序时XDP_TX
,其中一个内核处于 ~100% 的忙碌状态,ksoftirqd
并且只处理 ~4Mpps。在这里我不确定,为什么会这样。
您有什么想法,可能导致吞吐量下降和 CPU 使用率增加的原因是什么?
编辑:这里有一些关于机器 2 配置的更多细节:
# ethtool -g ens2f0
Ring parameters for ens2f0:
Pre-set maximums:
RX: 4096
RX Mini: n/a
RX Jumbo: n/a
TX: 4096
Current hardware settings:
RX: 512 # changing rx/tx to 4096 didn't help
RX Mini: n/a
RX Jumbo: n/a
TX: 512
# ethtool -l ens2f0
Channel parameters for ens2f0:
Pre-set maximums:
RX: n/a
TX: n/a
Other: 1
Combined: 63
Current hardware settings:
RX: n/a
TX: n/a
Other: 1
Combined: 32
# ethtool -x ens2f0
RX flow hash indirection table for ens2f0 with 32 RX ring(s):
0: 0 1 2 3 4 5 6 7
8: 8 9 10 11 12 13 14 15
16: 0 1 2 3 4 5 6 7
24: 8 9 10 11 12 13 14 15
32: 0 1 2 3 4 5 6 7
40: 8 9 10 11 12 13 14 15
48: 0 1 2 3 4 5 6 7
56: 8 9 10 11 12 13 14 15
64: 0 1 2 3 4 5 6 7
72: 8 9 10 11 12 13 14 15
80: 0 1 2 3 4 5 6 7
88: 8 9 10 11 12 13 14 15
96: 0 1 2 3 4 5 6 7
104: 8 9 10 11 12 13 14 15
112: 0 1 2 3 4 5 6 7
120: 8 9 10 11 12 13 14 15
RSS hash key:
d7:81:b1:8c:68:05:a9:eb:f4:24:86:f6:28:14:7e:f5:49:4e:29:ce:c7:2e:47:a0:08:f1:e9:31:b3:e5:45:a6:c1:30:52:37:e9:98:2d:c1
RSS hash function:
toeplitz: on
xor: off
crc32: off
# uname -a
Linux test-2 5.8.0-44-generic #50-Ubuntu SMP Tue Feb 9 06:29:41 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
编辑 2:我现在也尝试将 MoonGen 作为数据包生成器,并用 10Mpps 和 100 个不同的数据包变体(流)淹没机器 2。现在,当以最小的 CPU 负载丢弃所有这些数据包时,流量在内核之间的分布更好。但是XDP_TX
在处理 ~3Mpps 时仍然无法跟上并将单个内核加载到 100%。