[PATCH net v2 2/2] selftests: drv-net: ring_reconfig: skip tx stall test without channel config

From: Bilal Yazıcıoğlu

Date: Tue Nov 10 2026 - 11:24:58 EST


reconfig_tx_stall() needs at least two combined channels and already
skips devices which don't report enough of them. Two kinds of devices
make it fail instead:

- drivers without the ethtool get_channels op (e.g. e1000e) fail the
initial channels_get with -EOPNOTSUPP;
- drivers with get_channels but no set_channels which report fewer
active than maximum combined channels fail the attempt to enable a
second one with -EOPNOTSUPP, and then the restore registered for it.

Skip the test in both cases. When the change is rejected with
-EOPNOTSUPP nothing was changed, so its restore is dropped. Other
netlink errors are still reported as failures, and the restore is
still registered before the change as before.

The issue was found through AI-assisted source code analysis
(OpenAI Codex) and confirmed on a ThinkPad T480 with an Intel I219-V
(e1000e, 8086:15d8). As for the previous patch, an earlier version
with the same channel query handling was run against that device
with a stub environment and ethtool set requests blocked, and the
test was skipped. The set_channels case was only checked against an
emulated ethtool family.

Fixes: c98610c2eb70 ("selftests: drv-net: Test queue stall upon reconfig")
Signed-off-by: Bilal Yazıcıoğlu <ahmetbilalyazicioglu@xxxxxxxxx>
---
.../selftests/drivers/net/ring_reconfig.py | 20 +++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/ring_reconfig.py b/tools/testing/selftests/drivers/net/ring_reconfig.py
index c7491154d1d..d6e84550d67 100755
--- a/tools/testing/selftests/drivers/net/ring_reconfig.py
+++ b/tools/testing/selftests/drivers/net/ring_reconfig.py
@@ -37,6 +37,18 @@ def _channels_get_or_skip(cfg, ehdr):
raise


+def _channels_set_or_skip(cfg, req, restore):
+ """ Set the channel config, skip the test if the device can't. """
+ undo = defer(cfg.eth.channels_set, restore)
+ try:
+ cfg.eth.channels_set(req)
+ except NlError as e:
+ if e.error == errno.EOPNOTSUPP:
+ undo.cancel()
+ raise KsftSkipEx("device does not support changing channels") from e
+ raise
+
+
def channels(cfg) -> None:
"""
Twiddle channel counts in various combinations of parameters.
@@ -338,16 +350,16 @@ def reconfig_tx_stall(cfg) -> None:
other_queue = 0

ehdr = {'header': {'dev-index': cfg.ifindex}}
- chans = cfg.eth.channels_get(ehdr)
+ chans = _channels_get_or_skip(cfg, ehdr)

if "combined-max" not in chans:
raise KsftSkipEx("device does not support combined channels")
if chans.get("combined-max", 0) < 2:
raise KsftSkipEx("device does not support 2+ combined channels")
if chans["combined-count"] < 2:
- defer(cfg.eth.channels_set,
- ehdr | {"combined-count": chans["combined-count"]})
- cfg.eth.channels_set(ehdr | {"combined-count": 2})
+ _channels_set_or_skip(
+ cfg, ehdr | {"combined-count": 2},
+ ehdr | {"combined-count": chans["combined-count"]})

rings = cfg.eth.rings_get(ehdr)
if 'rx' not in rings or 'tx' not in rings:
--
2.56.0