Yes. These changes includes the feedback from @Spyros and @hnyman.
I hope it's not bad etiquette to repost the full thing to avoid confusion ...
Install this script in /etc/init.d/irqbalance-manual
:
#!/bin/sh /etc/rc.common
# Version 2023-05-29
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 https://forum.openwrt.org/t/dynalink-dl-wrx36-askey-rt5010w-ipq8072a-technical-discussion/110454/1743
xhci*) ;; # Crashes with USB drive https://forum.openwrt.org/t/dynalink-dl-wrx36-askey-rt5010w-ipq8072a-technical-discussion/110454/1736
*) "$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
}
start_service() {
reload_service
}
reload_service() {
AFFINITY=$AFFINITY_MIN
set_affinities set_affinity_per_cpu
}
stop_service() {
set_affinities set_affinity_shared
}
Then, enable it for future boots:
service irqbalance-manual enable
Also enable it immediately with:
service irqbalance-manual start
And in reply to @odhiambo, as @hnyman pointed out, this is the expected output: the IRQ balancing happens only once at boot and no service is kept running.