Fix lag spikes under Linux gaming with iwd
Fix recurring lag spikes under Linux
While playing Quake Live under Linux, I noticed that my main desktop1, connected via wifi had more fluctuating ping times, with recurring lag spikes, which are completely absent under Windows.
Quake Live is a multi-player game from the 19992 which has no ping compensation, but the nice benefit of a Lag-O-Meter. This means, a bad internet connection is directly noticeable as game freezes, that are additionally visualized in your HUD.
Non-working system tweaks
Thus, I started searching for common issues with the mt7921e driver, and tested the following tweaks, but none of them solved the lag spikes:
- Disable ASPM (Power Management)
sudo tee /etc/modprobe.d/mt7921e.conf <<EOF options mt7921e disable_aspm=1 EOF - Disable NetworkManager Powersaving
sudo tee /etc/NetworkManager/conf.d/wifi-powersave.conf <<EOF [connection] wifi.powersave = 2 EOF - Disable background scanning
sudo tee /etc/NetworkManager/dispatcher.d/disablebackgroundscanning.sh <<EOF #!/bin/bash set -e # Run only when an interface is up if [[ "$2" != "up" ]]; then exit 0 fi # Check that the interface that went up is a wireless one if iw dev | grep -wq "$1"; then ALL_NETS="$(busctl tree fi.w1.wpa_supplicant1 | grep -Eo '/fi/w1/wpa_supplicant1/Interfaces/.+/Networks/[[:digit:]]+')" for DBUS_PATH_TO_NET in $ALL_NETS; do busctl call --system \ fi.w1.wpa_supplicant1 \ "$DBUS_PATH_TO_NET" \ org.freedesktop.DBus.Properties Set \ ssv \ fi.w1.wpa_supplicant1.Network Properties \ 'a{sv}' 1 \ bgscan s "" done fi EOF
With all the power saving options and wifi background scanning disabled, pinging the local router still shows spikes:
64 bytes from 192.168.1.1: icmp_seq=770 ttl=64 time=4.05 ms
64 bytes from 192.168.1.1: icmp_seq=771 ttl=64 time=3.99 ms
64 bytes from 192.168.1.1: icmp_seq=772 ttl=64 time=1.66 ms
64 bytes from 192.168.1.1: icmp_seq=773 ttl=64 time=4.08 ms
64 bytes from 192.168.1.1: icmp_seq=774 ttl=64 time=3.47 ms
64 bytes from 192.168.1.1: icmp_seq=774 ttl=64 time=3.47 ms
64 bytes from 192.168.1.1: icmp_seq=775 ttl=64 time=58.7 ms
64 bytes from 192.168.1.1: icmp_seq=776 ttl=64 time=107 ms ## the following 6s are noticeable during gaming
64 bytes from 192.168.1.1: icmp_seq=777 ttl=64 time=161 ms
64 bytes from 192.168.1.1: icmp_seq=778 ttl=64 time=1.69 ms
64 bytes from 192.168.1.1: icmp_seq=779 ttl=64 time=15.5 ms
64 bytes from 192.168.1.1: icmp_seq=780 ttl=64 time=85.8 ms
64 bytes from 192.168.1.1: icmp_seq=781 ttl=64 time=20.1 ms
64 bytes from 192.168.1.1: icmp_seq=782 ttl=64 time=4.43 ms
64 bytes from 192.168.1.1: icmp_seq=783 ttl=64 time=1.86 ms
A somewhat stable, low ping between a few ms, here 2ms and 5ms, with a lag spike every few minutes. I correlated my spikes to the times the router requests a WPA group rekeying, which for the AVM FRITZ!Box 7530 AX is every 300s.
Intel has a good reputation of well written Linux drivers. Years ago, I replaced the WiFi card in my Lenovo P14s Gen 2 (AMD) with an Intel Wi-Fi 6 AX200 card. Running ping on the AC powered Thinkpad showed the same lag spikes every 300s.
Finally, after discovering iwd and how it’s related within the network stack and kernel, I gave it a try. It eliminated the lag spikes, and even lowered the ping times by a few milliseconds. Shown below are a few example pings to my router:
64 bytes from 192.168.1.1: icmp_seq=293 ttl=64 time=0.745 ms
64 bytes from 192.168.1.1: icmp_seq=294 ttl=64 time=0.729 ms
64 bytes from 192.168.1.1: icmp_seq=295 ttl=64 time=0.709 ms
64 bytes from 192.168.1.1: icmp_seq=296 ttl=64 time=0.714 ms
64 bytes from 192.168.1.1: icmp_seq=297 ttl=64 time=1.35 ms
64 bytes from 192.168.1.1: icmp_seq=298 ttl=64 time=1.07 ms
64 bytes from 192.168.1.1: icmp_seq=299 ttl=64 time=1.33 ms
64 bytes from 192.168.1.1: icmp_seq=300 ttl=64 time=0.715 ms
Install iwd
In Fedora 43, you need to install iwd and remove or replace wpa_supplicant and tell NetworkManager to use iwd instead:
# install iwd
dnf install iwd
# to keep wpa_supplicant and just disable it:
systemctl disable --now wpa_supplicant
# creating the override file
mkdir -Z /etc/NetworkManager/conf.d
cat > /etc/NetworkManager/conf.d/iwd.conf <<EOF
[device]
wifi.backend=iwd
EOF
# fixing the SELinux labels
restorecon -R /etc/NetworkManager
# if this does not work
#chcon -R system_u:object_r:NetworkManager_etc_t:s0 /etc/NetworkManager/conf.d
# reloading NetworkManager
systemctl restart NetworkManager
With iwd instead of wpa_supplicant, and no additional power saving options set, the mt7291e delivers stable ping times with no lag spikes during online gaming.