rpi-4: move/pin eth0 IRQs to CPU2

Move all eth0 IRQ processing to CPU2 instead of CPU1 which is the
default. CPU1 will continue handling all the USB interrupts which
also include USB-Ethernet adapter interrupts.

This significantly lowers the softirq load on CPU1 (from 99% to
less than 10%)

irqbalance could do the same and you can still run irqbalance
because the /etc/init.d/irq-eth-pin script will add the eth0 to
the ban list of irqbalance

See interrupt load with
  while true; do clear; cat /proc/interrupts; sleep 1; done
This commit is contained in:
Mads Meisner-Jensen
2021-05-15 15:02:02 +02:00
parent 0176f0668f
commit 30054d0855
2 changed files with 37 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
#!/bin/sh /etc/rc.common
uci_banirq=irqbalance.irqbalance.banirq
cpu_irq_eth=2
# Move eth0 IRQs to CPU1 (numbered 1-4 when writing)
# And ban irqbalance from messing with it
# The USB3 Ethernet IRQs cannot be moved and must stay on CPU0
irqs_eth0=$(sed -rn "s/^\s*([0-9]+):.*eth0$/\1/p" /proc/interrupts)
for n in ${irqs_eth0}; do
echo ${cpu_irq_eth} > /proc/irq/${n}/smp_affinity
if ! uci get ${uci_banirq} | grep -q ${n}; then
uci add_list ${uci_banirq}=${n}
fi
done
uci commit
logger -t "irq_eth_pin" "Moved eth0 IRQs ${irqs_eth0} to cpu${cpu_irq_eth}"
softirqs_move() {
# Move softirqs for network traffic to CPU2 and CPU3
# Maybe not a brilliant idea because the softirqs are probably better off
# being processed on the CPU that got the original IRQ
# (and that is exactly the default when the value is 0)
# NOTE: it appears that the openwrt 20.02-rc1 kernel has a bug that
# returns "No such file or directory" for /sys/class/net/eth1/queues/xps_cpus
for ifname in eth0; do # eth1
for f in $(find /sys/class/net/${ifname}/queues -name xps_cpus -o -name rps_cpus); do
if [ -f ${f} ]; then
echo "${f} = $(cat ${f})"
echo c >${f}
fi
done
done
}