Dynalink DL-WRX36 Askey RT5010W IPQ8072A technical discussion

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
}

4 Likes