Irqbalance and SQM

Hi everyone, as described on the SQM wiki, I'm using my router with Software Stream Acceleration enabled and Packet Steering disabled. However, I'm wondering if activating IRQ Balancing while Software Stream Acceleration is on would result in even better performance?

Well, why don't you try it out and report your findings back to this thread?

2 Likes

Since the wiki is in English, I'm actually wondering if I can use IRQBalance with software flow acceleration enabled.

IMO, those work for some and not for others. The best practice is to discover your lan & wan device names, then do a cat /proc/interrupts.

Example for my Flint2 Running OpenWrt Stock v24.10.5:

           CPU0       CPU1       CPU2       CPU3
 11:   11711914   12565651   11767795   12595041     GICv3  30 Level     arch_timer
 24:          0          0          0          0   mt-eint   9 Edge      keys
 61:         41          0          0          0   mt-eint  46 Level     mdio-bus:01
 62:          2          0          0          0   mt-eint  47 Level     mdio-bus:07
 81:      24883          0          0          0   mt-eint  66 Level     mt7530
116:         13          0          0          0     GICv3 155 Level     ttyS0
120:   29683900          0          0          0     GICv3 229 Level     15100000.ethernet
121:       1129   74492954          0          0     GICv3 230 Level     15100000.ethernet
122:          0          0          0          0     GICv3 142 Level     wdt_bark
123:       3581          0          0          0     GICv3 175 Level     11230000.mmc
124:          0          0          0          0    mt7530   0 Edge      mt7530-0:00
125:          0          0      23787          0    mt7530   1 Edge      mt7530-0:01
126:          0          0          0          0    mt7530   2 Edge      mt7530-0:02
127:          0          0       1096          0    mt7530   3 Edge      mt7530-0:03
128:          0          0          0          0     GICv3 205 Level     xhci-hcd:usb1
129:          0          0          0          0     GICv3 148 Level     10320000.crypto
130:          0          0          0          0     GICv3 149 Level     10320000.crypto
131:          0          0          0          0     GICv3 150 Level     10320000.crypto
132:          0          0          0          0     GICv3 151 Level     10320000.crypto
133:       1944          0          0   85854898     GICv3 245 Level     mt7915e
IPI0:     64573     346706     142982     105525       Rescheduling interrupts
IPI1:  44654909  101036256   91317788   36448343       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
IPI4:         0          0          0          0       Timer broadcast interrupts
IPI5:         0      14529      10097      17457       IRQ work interrupts
IPI6:         0          0          0          0       CPU wake-up interrupts
Err:          0

/etc/rc.local

# Wait for interfaces to be fully up
sleep 10

# ---------------------------------------------------------
# FINALIZED CPU AFFINITY MAP
# Core 0 (1): System/Misc, LAN (eth0, br-lan, lan1-5)
# Core 1-2 (2,4): WAN (eth1, ifb4eth1)
# Core 3 (8): Wireless (when active)
# ---------------------------------------------------------

echo 1 > /proc/irq/120/smp_affinity
echo e > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo e > /sys/class/net/br-lan/queues/rx-0/rps_cpus
for i in /sys/class/net/eth0/queues/tx-*/xps_cpus; do echo e > "$i"; done
for i in /sys/class/net/lan*/queues/rx-0/rps_cpus; do echo e > "$i"; done

echo 6 > /proc/irq/121/smp_affinity
echo e > /sys/class/net/eth1/queues/rx-0/rps_cpus
echo e > /sys/class/net/ifb4eth1/queues/rx-0/rps_cpus
for i in /sys/class/net/eth1/queues/tx-*/xps_cpus; do echo e > "$i"; done

echo 8 > /proc/irq/133/smp_affinity
for iface in phy0-ap0 phy1-ap0; do
    [ -d "/sys/class/net/$iface" ] && echo e > /sys/class/net/$iface/queues/rx-0/rps_cpus 2>/dev/null
done

# Allow more packets per "tick" to compensate for the slow 100Hz timer
echo 1000 > /proc/sys/net/core/netdev_budget

# Increase the backlog so packets don't overflow between the slow ticks
echo 5000 > /proc/sys/net/core/netdev_max_backlog

exit 0

1. Dedicated CPU Lanes

Instead of letting all data pile up on one core, it divides the work:

  • Core 0: Manages your Home Devices (LAN).
  • Cores 1-2: Dedicated to the Internet (WAN) for max speed.
  • Core 3: Reserved strictly for Wi-Fi stability.

2. Bigger "Storage Bins"

Because this router's internal clock is a bit slow, the script makes two vital changes:

  • Larger Bites: It tells the CPU to process 1,000 packets at a time (instead of the small default) so it doesn't fall behind.
  • Bigger Waiting Room: It increases the "Backlog" to 5,000, giving incoming data a place to sit if the CPU is momentarily busy.

The Result:

  • Lower Ping: Great for gaming because traffic doesn't get stuck behind other tasks.
  • No Stuttering: Prevents the router from "freezing" during heavy downloads.
  • Better Wi-Fi: Wireless signals get their own dedicated processing power.

Mine are like this

           CPU0       CPU1       CPU2       CPU3       
  8:    1990210    2135258    2339588    2656633  MIPS GIC Local   1  timer
  9:    5523094          0          0          0  MIPS GIC  63  IPI call
 10:          0    7087491          0          0  MIPS GIC  64  IPI call
 11:          0          0    2737452          0  MIPS GIC  65  IPI call
 12:          0          0          0    1500581  MIPS GIC  66  IPI call
 13:      11561          0          0          0  MIPS GIC  67  IPI resched
 14:          0      20545          0          0  MIPS GIC  68  IPI resched
 15:          0          0       3805          0  MIPS GIC  69  IPI resched
 16:          0          0          0       3395  MIPS GIC  70  IPI resched
 17:          0          0          0          0  MIPS GIC  19  1e000600.gpio-bank0, 1e000600.gpio-bank1, 1e000600.gpio-bank2
 18:         12          0          0          0  MIPS GIC  33  ttyS0
 19:    5440897          0          0          0  MIPS GIC  10  1e100000.ethernet
 20:          0          0          0          0  MIPS GIC  30  mt7530
 23:          0          0          0          0    mt7530   2  mt7530-0:02
 24:          0          0          0          0    mt7530   3  mt7530-0:03
 25:          0          0          0          0  mt7621-gpio  18  keys
 26:          0          0          0          0  MIPS GIC  26  1e004000.crypto
 27:         23          0          0          0  MIPS GIC  31  mt7603e
 28:        960          0          0   14096115  MIPS GIC  11  mt76x2e
ERR:      51150

You have LOTS of errors. run this:
for i in /proc/irq/*/smp_affinity_list; do echo -n "IRQ ${i#*/irq/}: "; cat $i; done

1 Like

Do you use irqbalance and packet_steering Package in the background!!

For irq for my wan i use vlan eth1.100, do i have to change

No. I have both either disabled/not installed. To each their own but I find them to be very inconsistent on various SOCs.

run this and we can see what you have:

grep . /proc/irq/*/smp_affinity
for i in /proc/irq/*/smp_affinity_list; do echo -n "IRQ ${i#*/irq/}: "; cat $i; done
ls /sys/class/net/eth*/queues/tx-*/xps_cpus | xargs cat
ls -l /sys/class/net/*/device
uci get network.wan.device

The basic idea is keep everything that isn't LAN & system related such as WAN, WiFi, etc off of eth0 but on dedicated processors, since modern systems have more than 2 cores. RPS should spread to everything but eth0. We add the hex numbers together for more than a single cpu...

Column 1 Column 2 Column 3 Column 4
Hex Binary Decimal
0 0 0
1 1 1
2 10 2
3 11 3
4 100 4
5 101 5
6 110 6
7 111 7
8 1000 8
9 1001 9
A 1010 10
B 1011 11
C 1100 12
D 1101 13
E 1110 14
F 1111 15
14 10100 20
3F 111111 63

The Example Math

The Hex e comes from a "bitmask" representing 4 CPU cores:

  • Core 0 = 1
  • Core 1 = 2
  • Core 2 = 4
  • Core 3 = 8

2+4+8=14 decimal
Converted to hex= e

1 Like
root@OpenWrt:~# for i in /proc/irq/*/smp_affinity_list; do
>   echo -n "IRQ ${i##*/irq/}: "
>   cat $i
> done
IRQ 0/smp_affinity_list: 0-3
IRQ 1/smp_affinity_list: 0-3
IRQ 10/smp_affinity_list: 0-3
IRQ 11/smp_affinity_list: 0-3
IRQ 12/smp_affinity_list: 0-3
IRQ 13/smp_affinity_list: 0-3
IRQ 14/smp_affinity_list: 0-3
IRQ 15/smp_affinity_list: 0-3
IRQ 16/smp_affinity_list: 0-3
IRQ 17/smp_affinity_list: 0-3
IRQ 18/smp_affinity_list: 0-3
IRQ 19/smp_affinity_list: 0-3
IRQ 2/smp_affinity_list: 0-3
IRQ 20/smp_affinity_list: 0-3
IRQ 23/smp_affinity_list: 0-3
IRQ 24/smp_affinity_list: 0-3
IRQ 25/smp_affinity_list: 0-3
IRQ 26/smp_affinity_list: 0-3
IRQ 27/smp_affinity_list: 0-3
IRQ 28/smp_affinity_list: 0-3
IRQ 3/smp_affinity_list: 0-3
IRQ 4/smp_affinity_list: 0-3
IRQ 5/smp_affinity_list: 0-3
IRQ 6/smp_affinity_list: 0-3
IRQ 7/smp_affinity_list: 0-3
IRQ 8/smp_affinity_list: 0-3
IRQ 9/smp_affinity_list: 0-3
root@OpenWrt:~# 

Last login: Tue Jan 20 14:18:42 on ttys000
arda@Arda-iMac ~ % ssh root@192.168.1.1


BusyBox v1.36.1 (2025-12-30 22:05:19 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 24.10.5, r29087-d9c5716d1d
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:~# grep . /proc/irq/*/smp_affinity
/proc/irq/0/smp_affinity:f
/proc/irq/1/smp_affinity:f
/proc/irq/10/smp_affinity:f
/proc/irq/11/smp_affinity:f
/proc/irq/12/smp_affinity:f
/proc/irq/13/smp_affinity:f
/proc/irq/14/smp_affinity:f
/proc/irq/15/smp_affinity:f
/proc/irq/16/smp_affinity:f
/proc/irq/17/smp_affinity:f
/proc/irq/18/smp_affinity:f
/proc/irq/19/smp_affinity:f
/proc/irq/2/smp_affinity:f
/proc/irq/20/smp_affinity:f
/proc/irq/23/smp_affinity:f
/proc/irq/24/smp_affinity:f
/proc/irq/25/smp_affinity:f
/proc/irq/26/smp_affinity:f
/proc/irq/27/smp_affinity:f
/proc/irq/28/smp_affinity:f
/proc/irq/3/smp_affinity:f
/proc/irq/4/smp_affinity:f
/proc/irq/5/smp_affinity:f
/proc/irq/6/smp_affinity:f
/proc/irq/7/smp_affinity:f
/proc/irq/8/smp_affinity:f
/proc/irq/9/smp_affinity:f
root@OpenWrt:~# for i in /proc/irq/*/smp_affinity_list; do echo -n "IRQ ${i##*/i
rq/}: "; cat $i; done
IRQ 0/smp_affinity_list: 0-3
IRQ 1/smp_affinity_list: 0-3
IRQ 10/smp_affinity_list: 0-3
IRQ 11/smp_affinity_list: 0-3
IRQ 12/smp_affinity_list: 0-3
IRQ 13/smp_affinity_list: 0-3
IRQ 14/smp_affinity_list: 0-3
IRQ 15/smp_affinity_list: 0-3
IRQ 16/smp_affinity_list: 0-3
IRQ 17/smp_affinity_list: 0-3
IRQ 18/smp_affinity_list: 0-3
IRQ 19/smp_affinity_list: 0-3
IRQ 2/smp_affinity_list: 0-3
IRQ 20/smp_affinity_list: 0-3
IRQ 23/smp_affinity_list: 0-3
IRQ 24/smp_affinity_list: 0-3
IRQ 25/smp_affinity_list: 0-3
IRQ 26/smp_affinity_list: 0-3
IRQ 27/smp_affinity_list: 0-3
IRQ 28/smp_affinity_list: 0-3
IRQ 3/smp_affinity_list: 0-3
IRQ 4/smp_affinity_list: 0-3
IRQ 5/smp_affinity_list: 0-3
IRQ 6/smp_affinity_list: 0-3
IRQ 7/smp_affinity_list: 0-3
IRQ 8/smp_affinity_list: 0-3
IRQ 9/smp_affinity_list: 0-3
root@OpenWrt:~# ls /sys/class/net/*/queues/tx-*/xps_cpus | xargs cat
cat: read error: No such file or directory
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
cat: read error: No such file or directory
cat: read error: No such file or directory
cat: read error: No such file or directory
cat: read error: No such file or directory
cat: read error: No such file or directory
cat: read error: No such file or directory
cat: read error: No such file or directory
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
root@OpenWrt:~# ls -l /sys/class/net/*/device
lrwxrwxrwx    1 root     root             0 Jan 19 23:33 /sys/class/net/eth0/device -> ../../../1e100000.ethernet
lrwxrwxrwx    1 root     root             0 Jan 19 23:33 /sys/class/net/lan1/device -> ../../../mdio-bus:1f
lrwxrwxrwx    1 root     root             0 Jan 19 23:33 /sys/class/net/lan2/device -> ../../../mdio-bus:1f
lrwxrwxrwx    1 root     root             0 Jan 19 23:33 /sys/class/net/phy1-ap0/device -> ../../../0000:01:00.0
lrwxrwxrwx    1 root     root             0 Jan 19 23:33 /sys/class/net/wan/device -> ../../../1e100000.ethernet
root@OpenWrt:~# uci get network.wan.device
wan.35
root@OpenWrt:~# 

I'm booting my router with this command, and my Ethernet connection is now splitting between CPU0 and CPU1. Is this correct?

sleep 5; echo e > /proc/irq/19/smp_affinity; [ -f /sys/class/net/eth0/queues/rx-0/rps_cpus ] && echo e > /sys/class/net/eth0/queues/rx-0/rps_cpus; for f in /sys/class/net/eth0/queues/tx-*/xps_cpus; do [ -f "$f" ] && echo e > "$f"; done; echo 32768 > /proc/sys/net/core/netdev_max_backlog

I use the same router Flint2 but im running openwrt ver. 24.10.3

root@OpenWrt:~# grep . /proc/irq/*/smp_affinity
/proc/irq/1/smp_affinity:f
/proc/irq/10/smp_affinity:f
/proc/irq/11/smp_affinity:f
/proc/irq/116/smp_affinity:f
/proc/irq/12/smp_affinity:f
/proc/irq/120/smp_affinity:1
/proc/irq/121/smp_affinity:6
/proc/irq/122/smp_affinity:f
/proc/irq/123/smp_affinity:f
/proc/irq/124/smp_affinity:f
/proc/irq/125/smp_affinity:f
/proc/irq/126/smp_affinity:f
/proc/irq/127/smp_affinity:f
/proc/irq/128/smp_affinity:f
/proc/irq/129/smp_affinity:1
/proc/irq/13/smp_affinity:f
/proc/irq/130/smp_affinity:2
/proc/irq/131/smp_affinity:4
/proc/irq/132/smp_affinity:8
/proc/irq/133/smp_affinity:8
/proc/irq/2/smp_affinity:f
/proc/irq/24/smp_affinity:f
/proc/irq/3/smp_affinity:f
/proc/irq/4/smp_affinity:f
/proc/irq/5/smp_affinity:f
/proc/irq/6/smp_affinity:f
/proc/irq/61/smp_affinity:f
/proc/irq/62/smp_affinity:f
/proc/irq/7/smp_affinity:f
/proc/irq/8/smp_affinity:f
/proc/irq/81/smp_affinity:f
/proc/irq/9/smp_affinity:f
root@OpenWrt:~# for i in /proc/irq/*/smp_affinity_list; do echo -n "IRQ ${i#*/irq/}: "; cat $i; done
IRQ 1/smp_affinity_list: 0-3
IRQ 10/smp_affinity_list: 0-3
IRQ 11/smp_affinity_list: 0-3
IRQ 116/smp_affinity_list: 0-3
IRQ 12/smp_affinity_list: 0-3
IRQ 120/smp_affinity_list: 0
IRQ 121/smp_affinity_list: 1-2
IRQ 122/smp_affinity_list: 0-3
IRQ 123/smp_affinity_list: 0-3
IRQ 124/smp_affinity_list: 0-3
IRQ 125/smp_affinity_list: 0-3
IRQ 126/smp_affinity_list: 0-3
IRQ 127/smp_affinity_list: 0-3
IRQ 128/smp_affinity_list: 0-3
IRQ 129/smp_affinity_list: 0
IRQ 13/smp_affinity_list: 0-3
IRQ 130/smp_affinity_list: 1
IRQ 131/smp_affinity_list: 2
IRQ 132/smp_affinity_list: 3
IRQ 133/smp_affinity_list: 3
IRQ 2/smp_affinity_list: 0-3
IRQ 24/smp_affinity_list: 0-3
IRQ 3/smp_affinity_list: 0-3
IRQ 4/smp_affinity_list: 0-3
IRQ 5/smp_affinity_list: 0-3
IRQ 6/smp_affinity_list: 0-3
IRQ 61/smp_affinity_list: 0-3
IRQ 62/smp_affinity_list: 0-3
IRQ 7/smp_affinity_list: 0-3
IRQ 8/smp_affinity_list: 0-3
IRQ 81/smp_affinity_list: 0-3
IRQ 9/smp_affinity_list: 0-3
root@OpenWrt:~# ls /sys/class/net/eth*/queues/tx-*/xps_cpus | xargs cat
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
cat: read error: No such file or directory
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
root@OpenWrt:~# ls -l /sys/class/net/*/device
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/eth0/device -> ../../../15100000.ethernet
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/eth1/device -> ../../../15100000.ethernet
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/lan1/device -> ../../../mdio-bus:1f
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/lan2/device -> ../../../mdio-bus:1f
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/lan3/device -> ../../../mdio-bus:1f
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/lan4/device -> ../../../mdio-bus:1f
lrwxrwxrwx    1 root     root             0 Jan 19 23:04 /sys/class/net/lan5/device -> ../../../mdio-bus:1f
root@OpenWrt:~# uci get network.wan.device
eth1.100

How many total cores do you have?

please paste the output of:

cat /proc/interrupts

e means to use cores 1-3, NOT 0.

How many total cores do you have?

please paste the output of:

cat /proc/interrupts

GL.iNet GL-MT6000 have 4 cores

root@OpenWrt:~# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
 11:     260196     963626    1142905     689929     GICv3  30 Level     arch_timer
 24:          0          0          0          0   mt-eint   9 Edge      keys
 61:         13          0          0          0   mt-eint  46 Level     mdio-bus:01
 62:          2          0          0          0   mt-eint  47 Level     mdio-bus:07
 81:          6          0          0          0   mt-eint  66 Level     mt7530
116:         13          0          0          0     GICv3 155 Level     ttyS0
120:    1115701          0          0          0     GICv3 229 Level     15100000.ethernet
121:       2825    1126862          0          0     GICv3 230 Level     15100000.ethernet
122:          0          0          0          0     GICv3 142 Level     wdt_bark
123:       2262          0          0          0     GICv3 175 Level     11230000.mmc
124:          3          0          0          0    mt7530   0 Edge      mt7530-0:00
125:          3          0          0          0    mt7530   1 Edge      mt7530-0:01
126:          0          0          0          0    mt7530   2 Edge      mt7530-0:02
127:          0          0          0          0    mt7530   3 Edge      mt7530-0:03
128:          0          0          0          0     GICv3 205 Level     xhci-hcd:usb1
129:          0          0          0          0     GICv3 148 Level     10320000.crypto
130:          0          0          0          0     GICv3 149 Level     10320000.crypto
131:          0          0          0          0     GICv3 150 Level     10320000.crypto
132:          0          0          0          0     GICv3 151 Level     10320000.crypto
133:        744          0          0          0     GICv3 245 Level     mt7915e
IPI0:      7980       7731       8549       8374       Rescheduling interrupts
IPI1:    276988     779298     975287     687185       Function call interrupts
IPI2:         0          0          0          0       CPU stop interrupts
IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
IPI4:         0          0          0          0       Timer broadcast interrupts
IPI5:         0          0          0          0       IRQ work interrupts
IPI6:         0          0          0          0       CPU wake-up interrupts
Err:          0

Breakdown of Operations

1. Wait Period

  • sleep 10: Ensures network interfaces are fully initialized before applying hardware-level configurations.

2. Core 0: System & LAN Management

  • IRQ 120 (eth0): Bound to Core 0 (affinity 1).
  • RPS/XPS: Configures Receive Packet Steering (RPS) and Transmit Packet Steering (XPS) for eth0, br-lan, and individual lan* ports.
  • Mask e: Despite the comment suggesting Core 0, the mask e (binary 1110) actually delegates software processing to Cores 1, 2, and 3, keeping Core 0 free for hardware interrupts and system tasks.

3. Cores 1–2: WAN Traffic

  • IRQ 121 (eth1): Bound to Cores 1 and 2 (affinity 6, binary 0110).
  • Traffic Shaping: Applies RPS/XPS to eth1 and its associated Intermediate Functional Block (ifb4eth1), which is typically used for bufferbloat control (SQM).

4. Core 3: Wireless Operations

  • IRQ 133 (WiFi): Bound to Core 3 (affinity 8, binary 1000).
  • Wireless Interfaces: Directs software packet steering for phy0-ap0 and phy1-ap0 (2.4GHz and 5GHz radios) to this core to prevent WiFi processing from lagging the wired WAN/LAN.

5. Kernel Tuning for Low-HZ Systems

  • netdev_budget (1000): Increases the number of packets the CPU can process in one interrupt "poll" cycle.
  • netdev_max_backlog (5000): Increases the queue size for packets waiting to be processed by the CPU, preventing drops during sudden traffic spikes.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.