Dynalink DL-WRX36 Askey RT5010W IPQ8072A technical discussion

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 :slight_smile:...

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.

7 Likes