前言
RK3588 是 big.LITTLE 的架构,有 4 个小核 (0-3) 和 4 个大核 (4-7),排查下来发现,是系统自动把第一张网卡设置在一个小核 (3) 上,另一张网卡绑定在大核 (4) 上,在 top 所见就是 ksoftirqd/3 和 ksoftirqd/4 在打流量时占用较高,其中 3 和 4 代表的就是 CPU 核心。
思路和方法
下文以作者的网卡 ID enP4p65s0 和 enP3p49s0 为准。
思路
使用网卡跑一些流量,然后查看网卡 IRQ
cat /proc/interrupts | grep enP可以看到从左到右是 IRQ 各 CPU 核心,应当可以看到有几个数字会比较大,然后按从左往右依次为 0-7 核,例如下方主要是跑在 CPU5:
...
189: 0 0 0 6 0 268089 0 0 ITS-MSI 428343296 Edge enP3p49s0-0
...
205: 0 0 0 8 0 61409 0 0 ITS-MSI 428343312 Edge enP3p49s0-16
...如果未设置,可能会跑在 CPU3 或 CPU4
查看网卡队列亲和性 (RPS/XPS)
ls /sys/class/net/enP*/queues/*/{r,x}ps_cpus
cat /sys/class/net/enP*/queues/*/{r,x}ps_cpus可以看到默认都是 00, 即没有绑定在任何核心
# ls /sys/class/net/enP*/queues/*/{r,x}ps_cpus
/sys/class/net/enP3p49s0/queues/rx-0/rps_cpus /sys/class/net/enP3p49s0/queues/tx-0/xps_cpus /sys/class/net/enP4p65s0/queues/rx-0/rps_cpus /sys/class/net/enP4p65s0/queues/tx-0/xps_cpus
# cat /sys/class/net/enP*/queues/*/{r,x}ps_cpus
00
00
00
00其中 CPU 掩码按如下规律:
如果要选择到所有大核 (4-7),那么可以将 4-7 的 BIN 或起来,即 1111 0000,HEX 是 0xf0
方法
设置网卡队列亲和性 (RPS/XPS),设置到所有大核
for q in /sys/class/net/enP3p49s0/queues/rx-*; do
echo f0 > $q/rps_cpus
done
for q in /sys/class/net/enP3p49s0/queues/tx-*; do
echo f0 > $q/xps_cpus
done
for q in /sys/class/net/enP4p65s0/queues/rx-*; do
echo f0 > $q/rps_cpus
done
for q in /sys/class/net/enP4p65s0/queues/tx-*; do
echo f0 > $q/xps_cpus
done设置网卡 IRQ 亲和性
for line in $(grep enP /proc/interrupts | awk -F':' '{print $1}'); do
echo f0 > /proc/irq/$line/smp_affinity
done再度测试,性能可能就会相较之前更好
设置开机自启
创建脚本 /usr/local/bin/set-irq-affinity.sh
#!/bin/bash
while [ ! -e /proc/interrupts ]; do
sleep 1
done
while ! grep -q enP3p49s0 /proc/interrupts; do
sleep 1
done
while ! grep -q enP4p65s0 /proc/interrupts; do
sleep 1
done
sleep 5
for q in /sys/class/net/enP3p49s0/queues/rx-*; do
echo f0 > $q/rps_cpus
done
for q in /sys/class/net/enP3p49s0/queues/tx-*; do
echo f0 > $q/xps_cpus
done
for q in /sys/class/net/enP4p65s0/queues/rx-*; do
echo f0 > $q/rps_cpus
done
for q in /sys/class/net/enP4p65s0/queues/tx-*; do
echo f0 > $q/xps_cpus
done
for line in $(grep enP /proc/interrupts | awk -F':' '{print $1}'); do
echo f0 > /proc/irq/$line/smp_affinity
done添加执行权限
chmod +x /usr/local/bin/set-irq-affinity.sh设置 systemd 服务
vim /etc/systemd/system/set-irq-affinity.service写入如下:
[Unit]
Description=Set IRQ affinity
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/set-irq-affinity.sh &
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target设置开机自启
systemctl daemon-reload
systemctl enable --now set-irq-affinity.service重启查看是否生效
cat /sys/class/net/enP*/queues/*/{r,x}ps_cpus
cat /proc/interrupts | grep enP|awk -F':' '{print $1}'|while read line; do cat /proc/irq/$line/smp_affinity; done都是 f0 即已设置成功