mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Bilal Yazıcıoğlu" <ahmetbilalyazicioglu@gmail.com>
To: netdev@vger.kernel.org
Cc: "Andrew Lunn" <andrew+netdev@lunn.ch>,
	"David S . Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@kernel.org>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Shuah Khan" <shuah@kernel.org>,
	"Mohsin Bashir" <hmohsin@meta.com>,
	linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Bilal Yazıcıoğlu" <ahmetbilalyazicioglu@gmail.com>
Subject: [PATCH net v2 1/2] selftests: drv-net: ring_reconfig: handle devices without channel config
Date: Tue, 10 Nov 2026 19:14:22 +0300	[thread overview]
Message-ID: <20261110161423.77910-2-ahmetbilalyazicioglu@gmail.com> (raw)
In-Reply-To: <20261110161423.77910-1-ahmetbilalyazicioglu@gmail.com>

Drivers which don't implement the ethtool get_channels op (e.g.
e1000e) make ETHTOOL_MSG_CHANNELS_GET fail with -EOPNOTSUPP, and
drivers which implement get_channels but not set_channels (e.g.
vmxnet3, r8169) make ETHTOOL_MSG_CHANNELS_SET fail the same way. YNL
raises that as an NlError, so ring_reconfig reports failures on such
devices:

 - channels() fails on its first channels_get call or, if the device
   can't change channels, when restoring the original counts;
 - ringparam() fails in _configure_min_ring_cnt() before any ring
   size is tested. The helper only reduces the channel count to
   speed up the reconfiguration, ringparam() does not depend on it.

Skip channels() when the channel query is not supported, or when every
channel layout it tries is rejected with -EOPNOTSUPP; nothing was
changed in that case, so the restore is dropped. Return early from
_configure_min_ring_cnt() when the channel count can't be queried or
changed, logging that it was left unchanged. Other netlink errors are
still reported as failures.

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): "ethtool -l" fails with "Operation not
supported" while "ethtool -g" works, and running the test functions
with the in-tree YNL library against the device fails with NlError
95 (EOPNOTSUPP). The get_channels-only case was reported by the
Sashiko AI review of v1.

No remote endpoint was available, so the full test was not run. On
the same machine, an earlier version of this patch with the same
channel query handling was run under ksft_run with a stub
environment and all ethtool set requests blocked: channels() was
skipped and _configure_min_ring_cnt() returned after the channel
query. The handling of a rejected channel change, and devices which
support changing channels, were only checked against an emulated
ethtool family.

Fixes: ecca75ae5ae6 ("selftests: drv-net: replace the nsim ring test with a drv-net one")
Signed-off-by: Bilal Yazıcıoğlu <ahmetbilalyazicioglu@gmail.com>
---

Notes:
    Note, not part of this fix: with this patch ringparam() gets past
    _configure_min_ring_cnt() on e1000e and reaches the ring size loop.
    e1000e clamps ring sizes below 64 instead of rejecting them, so the
    check that the requested minimum was applied is expected to fail on
    that driver. I could not run that part (it needs a remote endpoint),
    and whether the test or the driver should change is a separate
    question.

 .../selftests/drivers/net/ring_reconfig.py    | 45 +++++++++++++++++--
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/ring_reconfig.py b/tools/testing/selftests/drivers/net/ring_reconfig.py
index 6682d4badfb..c7491154d1d 100755
--- a/tools/testing/selftests/drivers/net/ring_reconfig.py
+++ b/tools/testing/selftests/drivers/net/ring_reconfig.py
@@ -5,6 +5,7 @@
 Test channel and ring size configuration via ethtool (-L / -G).
 """
 
+import errno
 import socket
 import struct
 import time
@@ -26,6 +27,16 @@ MIN_TX_RING = 32
 MAX_TX_RING = 1024
 
 
+def _channels_get_or_skip(cfg, ehdr):
+    """ Get the channel config, skip the test if the device has none. """
+    try:
+        return cfg.eth.channels_get(ehdr)
+    except NlError as e:
+        if e.error == errno.EOPNOTSUPP:
+            raise KsftSkipEx("device does not support channel config") from e
+        raise
+
+
 def channels(cfg) -> None:
     """
     Twiddle channel counts in various combinations of parameters.
@@ -33,7 +44,7 @@ def channels(cfg) -> None:
     if the config is accepted and crashes.
     """
     ehdr = {'header':{'dev-index': cfg.ifindex}}
-    chans = cfg.eth.channels_get(ehdr)
+    chans = _channels_get_or_skip(cfg, ehdr)
 
     all_keys = ["rx", "tx", "combined"]
     mixes = [{"combined"}, {"rx", "tx"}, {"rx", "combined"}, {"tx", "combined"},
@@ -47,21 +58,26 @@ def channels(cfg) -> None:
             supported.add(key)
             restore |= {key + "-count": chans[key + "-count"]}
 
-    defer(cfg.eth.channels_set, ehdr | restore)
+    restore_chans = defer(cfg.eth.channels_set, ehdr | restore)
 
     def test_config(config):
+        applied = False
         try:
             cfg.eth.channels_set(ehdr | config)
+            applied = True
             get = cfg.eth.channels_get(ehdr)
             for k, v in config.items():
                 ksft_eq(get.get(k, 0), v)
         except NlError as e:
             failed.append(mix)
+            if e.error == errno.EOPNOTSUPP and not applied:
+                unsupported.append(mix)
             ksft_pr("Can't set", config, e)
         else:
             ksft_pr("Okay", config)
 
     failed = []
+    unsupported = []
     for mix in mixes:
         if not mix.issubset(supported):
             continue
@@ -72,6 +88,13 @@ def channels(cfg) -> None:
             config[key + "-count"] = 1 if key in mix else 0
         test_config(config)
 
+    # Every config was rejected as unsupported, so nothing was changed:
+    # the device reports channels but can't change them
+    attempted = [m for m in mixes if m.issubset(supported)]
+    if attempted and unsupported == attempted:
+        restore_chans.cancel()
+        raise KsftSkipEx("device does not support changing channels")
+
     for mix in mixes:
         if not mix.issubset(supported):
             continue
@@ -88,7 +111,14 @@ def channels(cfg) -> None:
 def _configure_min_ring_cnt(cfg) -> None:
     """ Try to configure a single Rx/Tx ring. """
     ehdr = {'header':{'dev-index': cfg.ifindex}}
-    chans = cfg.eth.channels_get(ehdr)
+    try:
+        chans = cfg.eth.channels_get(ehdr)
+    except NlError as e:
+        # Reducing the channel count is only an optimization
+        if e.error == errno.EOPNOTSUPP:
+            ksft_pr("Channel configuration unsupported; continuing ring test")
+            return
+        raise
 
     all_keys = ["rx-count", "tx-count", "combined-count"]
     restore = {}
@@ -107,7 +137,14 @@ def _configure_min_ring_cnt(cfg) -> None:
         # looks like we're already on 1 channel
         return
 
-    cfg.eth.channels_set(ehdr | config)
+    try:
+        cfg.eth.channels_set(ehdr | config)
+    except NlError as e:
+        # Some drivers report channels but can't change them
+        if e.error == errno.EOPNOTSUPP:
+            ksft_pr("Channel configuration unsupported; continuing ring test")
+            return
+        raise
     defer(cfg.eth.channels_set, ehdr | restore)
 
 
-- 
2.56.0


  reply	other threads:[~2026-11-10 16:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 16:14 [PATCH net v2 0/2] " Bilal Yazıcıoğlu
2026-11-10 16:14 ` Bilal Yazıcıoğlu [this message]
2026-11-10 16:14 ` [PATCH net v2 2/2] selftests: drv-net: ring_reconfig: skip tx stall test " Bilal Yazıcıoğlu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261110161423.77910-2-ahmetbilalyazicioglu@gmail.com \
    --to=ahmetbilalyazicioglu@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=hmohsin@meta.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®