Since I have IPQ087x devices running OpenWrt I was using a pretty basic script adjusting just a few IRQs. And I saw serveral scripts in this forum about this topic. They are quite scattered. So I've summed it up a bit.
I've taken the script of @fif since a while now and it is running stable on AX3600 and NBG7815. The only things I've added in addtion is setting rx/tx rps_cpus as well. It is killing a running irqbalance too (just in case). I've added the full device list also because I had it already to put the script just in files and forget it.
The only thing what I still not understand is that ppl. do set rx and tx to the same CPU. While I do think it has to be the opposite for the other side (from a logical standpoint). It would be nice if someone could clearify this point.
#!/bin/sh /etc/rc.common
# from: https://forum.openwrt.org/t/dynalink-dl-wrx36-askey-rt5010w-ipq8072a-technical-discussion/110454/1752
START=13
USE_PROCD=1
AFFINITY_MIN=2
AFFINITY_MAX=8
AFFINITY_ALL="$(printf %x $(( AFFINITY_MAX * 2 - 1 )))"
set_affinities() {
local callback="$1" irq desc ret=0
sed -nre 's!^[[:space:]]*([0-9]+):[[:space:]]+.*[[:space:]]GIC-0[[:space:]]+[0-9]+[[:space:]]+(Level|Edge)[[:space:]]+(.+)$!\1 \3! p' /proc/interrupts | \
while read irq desc
do
case "$desc" in
arch*) ;; # Properly balanced
ce*) ;; # Wifi firmware crashes
edma*) ;; # Hangs wifi on high throughput
xhci*) ;; # Crashes with USB drive
*) "$callback" "/proc/irq/$irq/smp_affinity" || ret=1 ;;
esac
done
return $ret
}
set_affinity_per_cpu() {
local procfile="$1" ret=0
echo "$AFFINITY" > "$procfile" || ret=$?
if [ $AFFINITY -ge $AFFINITY_MAX ]
then
AFFINITY=$AFFINITY_MIN
else
AFFINITY=$(( AFFINITY * 2 ))
fi
return $ret
}
set_affinity_shared() {
local procfile="$1" ret=0
echo "$AFFINITY_ALL" > "$procfile" || ret=$?
return $ret
}
set_affinity_lan() {
for i in /sys/class/net/lan*/queues/rx-0/rps_cpus ; do echo "1" > "$i"; done
for i in /sys/class/net/lan*/queues/rx-1/rps_cpus ; do echo "2" > "$i"; done
for i in /sys/class/net/lan*/queues/rx-2/rps_cpus ; do echo "4" > "$i"; done
for i in /sys/class/net/lan*/queues/rx-3/rps_cpus ; do echo "8" > "$i"; done
for i in /sys/class/net/lan*/queues/tx-0/rps_cpus ; do echo "8" > "$i"; done
for i in /sys/class/net/lan*/queues/tx-1/rps_cpus ; do echo "4" > "$i"; done
for i in /sys/class/net/lan*/queues/tx-2/rps_cpus ; do echo "2" > "$i"; done
for i in /sys/class/net/lan*/queues/tx-3/rps_cpus ; do echo "1" > "$i"; done
for i in /sys/class/net/10g*/queues/rx-0/rps_cpus ; do echo "1" > "$i"; done
for i in /sys/class/net/10g*/queues/rx-1/rps_cpus ; do echo "2" > "$i"; done
for i in /sys/class/net/10g*/queues/rx-2/rps_cpus ; do echo "4" > "$i"; done
for i in /sys/class/net/10g*/queues/rx-3/rps_cpus ; do echo "8" > "$i"; done
for i in /sys/class/net/10g*/queues/tx-0/rps_cpus ; do echo "8" > "$i"; done
for i in /sys/class/net/10g*/queues/tx-1/rps_cpus ; do echo "4" > "$i"; done
for i in /sys/class/net/10g*/queues/tx-2/rps_cpus ; do echo "2" > "$i"; done
for i in /sys/class/net/10g*/queues/tx-3/rps_cpus ; do echo "1" > "$i"; done
}
kill_irqbalance() {
if [ $(/etc/init.d/irqbalance status) = "running" ]; then /etc/init.d/irqbalance stop && /etc/init.d/irqbalance disable; fi
(! pidof irqbalance) || kill -9 $(pidof irqbalance)
}
set_affinity_ipq807x() {
case $(board_name) in
buffalo,wxr-5950ax12|\
compex,wpq873|\
dynalink,dl-wrx36|\
edgecore,eap102|\
edimax,cax1800|\
netgear,rax120v2|\
netgear,wax218|\
netgear,wax620|\
netgear,wax630|\
prpl,haze|\
qnap,301w|\
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000|\
yuncore,ax880|\
zyxel,nbg7815)
kill_irqbalance
AFFINITY=$AFFINITY_MIN
set_affinities set_affinity_per_cpu
set_affinity_lan
;;
esac
}
start_service() {
reload_service
}
reload_service() {
set_affinity_ipq807x
}
stop_service() {
set_affinities
set_affinity_shared
}