iaun
iaun
发布于 2026-02-22 / 25 阅读
0
0

RK3588 开发板设定网卡 CPU 亲和性

前言

RK3588 是 big.LITTLE 的架构,有 4 个小核 (0-3) 和 4 个大核 (4-7),排查下来发现,是系统自动把第一张网卡设置在一个小核 (3) 上,另一张网卡绑定在大核 (4) 上,在 top 所见就是 ksoftirqd/3 和 ksoftirqd/4 在打流量时占用较高,其中 3 和 4 代表的就是 CPU 核心。

思路和方法

下文以作者的网卡 ID enP4p65s0 和 enP3p49s0 为准。

思路

  1. 使用网卡跑一些流量,然后查看网卡 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

  1. 查看网卡队列亲和性 (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 掩码按如下规律:

CPU

BIN

HEX

0

0000 0001

0x01

1

0000 0010

0x02

...

...

...

4

0001 0000

0x10

5

0010 0000

0x20

6

0100 0000

0x40

7

1000 0000

0x80

如果要选择到所有大核 (4-7),那么可以将 4-7 的 BIN 或起来,即 1111 0000,HEX 是 0xf0

方法

  1. 设置网卡队列亲和性 (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

  1. 设置网卡 IRQ 亲和性

for line in $(grep enP /proc/interrupts | awk -F':' '{print $1}'); do
    echo f0 > /proc/irq/$line/smp_affinity
done

  1. 再度测试,性能可能就会相较之前更好

设置开机自启

  1. 创建脚本 /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
  1. 添加执行权限

chmod +x /usr/local/bin/set-irq-affinity.sh
  1. 设置 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
  1. 设置开机自启

systemctl daemon-reload
systemctl enable --now set-irq-affinity.service
  1. 重启查看是否生效

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 即已设置成功


评论