9.2. 避免 TX 队列锁争用:传输数据包控制
在具有支持多个队列的网络接口控制器(NIC)的主机中,传输数据包控制(XPS)将传出网络数据包的处理分发到多个队列。这可让多个 CPU 处理传出网络流量,并避免传输队列锁争用,从而避免数据包丢弃。
某些驱动程序,如 ixgbe
、i40e
和 mlx5
会自动配置 XPS。要识别驱动程序是否支持此功能,请咨询 NIC 驱动程序文档。请咨询您的 NIC 驱动程序文档来识别驱动程序是否支持此功能。如果驱动程序不支持 XPS 自动调优,您可以手动将 CPU 核分配给传输队列。
Red Hat Enterprise Linux 不提供一个将传输队列永久分配给 CPU 核的选项。使用在接口被激活时执行的 NetworkManager 分配程序脚本中的命令。详情请参阅 如何编写一个 NetworkManager 分配程序脚本,以便在接口启动时应用命令。
有关在 Linux 网络堆栈中扩展的详情,请查看 kernel-doc
软件包提供的 /usr/share/doc/kernel-doc- <version> /Documentation/networking/scaling.rst
文件。
先决条件
- NIC 支持多个队列。
-
numactl
软件包已安装。
流程
显示可用队列的数量:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Pre-set maximums
部分显示队列的总数,Current hardware settings
显示当前分配给接收、传输、其他或组合队列的队列数。可选:如果您需要特定通道上的队列,请相应地分配它们。例如,要将 4 个队列分配给
Combined
通道,请输入:ethtool -L enp1s0 combined 4
# ethtool -L enp1s0 combined 4
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 显示 NIC 被分配给了哪个 Non-Uniform Memory Access (NUMA)节点:
cat /sys/class/net/enp1s0/device/numa_node 0
# cat /sys/class/net/enp1s0/device/numa_node 0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果文件未找到,或者命令返回
-1,
则主机不是 NUMA 系统。如果主机是 NUMA 系统,显示哪些 CPU 被分配给了哪个 NUMA 节点:
lscpu | grep NUMA
# lscpu | grep NUMA NUMA node(s): 2 NUMA node0 CPU(s): 0-3 NUMA node1 CPU(s): 4-7
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在上例中,NIC 有 4 个队列,NIC 被分配给 NUMA 节点 0。此节点使用 CPU 核 0-3。因此,将每个传输队列映射到 CPU 核 0-3 中的一个:
echo 1 > /sys/class/net/enp1s0/queues/tx-0/xps_cpus echo 2 > /sys/class/net/enp1s0/queues/tx-1/xps_cpus echo 4 > /sys/class/net/enp1s0/queues/tx-2/xps_cpus echo 8 > /sys/class/net/enp1s0/queues/tx-3/xps_cpus
# echo 1 > /sys/class/net/enp1s0/queues/tx-0/xps_cpus # echo 2 > /sys/class/net/enp1s0/queues/tx-1/xps_cpus # echo 4 > /sys/class/net/enp1s0/queues/tx-2/xps_cpus # echo 8 > /sys/class/net/enp1s0/queues/tx-3/xps_cpus
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果 CPU 核数和传输(TX)队列相同,请使用 1 对 1 映射,以避免 TX 队列上的任何类型的争用。否则,如果您在同一 TX 队列上映射多个 CPU,则不同 CPU 上的传输操作将导致 TX 队列锁竞争,并对传输吞吐量造成负面影响。
请注意,您必须将包含 CPU 核号的位图传给队列。使用以下命令计算位图:
printf %x $((1 << <core_number> ))
# printf %x $((1 << <core_number> ))
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证
识别发送流量的服务的进程 ID (PID):
pidof <process_name>
# pidof <process_name> 12345 98765
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将 PID 固定到使用 XPS 的核:
numactl -C 0-3 12345 98765
# numactl -C 0-3 12345 98765
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在进程发送流量时监控
requeues
计数器:tc -s qdisc
# tc -s qdisc qdisc fq_codel 0: dev enp10s0u1 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64 Sent 125728849 bytes 1067587 pkt (dropped 0, overlimits 0 requeues 30) backlog 0b 0p requeues 30 ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果
requeues
计数器不再以显著速率增加,则 TX 队列锁争用不再发生。