[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251120033016.3809474-3-dw@davidwei.uk>
Date: Wed, 19 Nov 2025 19:30:11 -0800
From: David Wei <dw@...idwei.uk>
To: netdev@...r.kernel.org
Cc: Andrew Lunn <andrew+netdev@...n.ch>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Daniel Borkmann <daniel@...earbox.net>
Subject: [PATCH net-next v1 2/7] selftests/net: add MemPrvEnv env
Memory provider HW selftests (i.e. zcrx, devmem) require setting up a
netdev with e.g. flow steering rules. Add a new MemPrvEnv that sets up
the test env, restoring it to the original state prior to the test. This
also speeds up tests since each individual test case don't need to
repeat the setup/teardown.
Signed-off-by: David Wei <dw@...idwei.uk>
---
.../drivers/net/hw/lib/py/__init__.py | 5 +-
.../selftests/drivers/net/lib/py/__init__.py | 4 +-
.../selftests/drivers/net/lib/py/env.py | 71 ++++++++++++++++++-
3 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py b/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py
index fb010a48a5a1..09f120be9075 100644
--- a/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py
+++ b/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py
@@ -29,7 +29,7 @@ try:
from net.lib.py import ksft_eq, ksft_ge, ksft_in, ksft_is, ksft_lt, \
ksft_ne, ksft_not_in, ksft_raises, ksft_true, ksft_gt, ksft_not_none
from drivers.net.lib.py import GenerateTraffic, Remote
- from drivers.net.lib.py import NetDrvEnv, NetDrvEpEnv
+ from drivers.net.lib.py import NetDrvEnv, NetDrvEpEnv, MemPrvEnv
__all__ = ["NetNS", "NetNSEnter", "NetdevSimDev",
"EthtoolFamily", "NetdevFamily", "NetshaperFamily",
@@ -44,7 +44,8 @@ try:
"ksft_eq", "ksft_ge", "ksft_in", "ksft_is", "ksft_lt",
"ksft_ne", "ksft_not_in", "ksft_raises", "ksft_true", "ksft_gt",
"ksft_not_none", "ksft_not_none",
- "NetDrvEnv", "NetDrvEpEnv", "GenerateTraffic", "Remote"]
+ "GenerateTraffic", "Remote",
+ "NetDrvEnv", "NetDrvEpEnv", "MemPrvEnv"]
except ModuleNotFoundError as e:
print("Failed importing `net` library from kernel sources")
print(str(e))
diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py
index b0c6300150fb..dde4e80811c7 100644
--- a/tools/testing/selftests/drivers/net/lib/py/__init__.py
+++ b/tools/testing/selftests/drivers/net/lib/py/__init__.py
@@ -43,11 +43,11 @@ try:
"ksft_ne", "ksft_not_in", "ksft_raises", "ksft_true", "ksft_gt",
"ksft_not_none", "ksft_not_none"]
- from .env import NetDrvEnv, NetDrvEpEnv
+ from .env import NetDrvEnv, NetDrvEpEnv, MemPrvEnv
from .load import GenerateTraffic
from .remote import Remote
- __all__ += ["NetDrvEnv", "NetDrvEpEnv", "GenerateTraffic", "Remote"]
+ __all__ += ["NetDrvEnv", "NetDrvEpEnv", "MemPrvEnv", "GenerateTraffic", "Remote"]
except ModuleNotFoundError as e:
print("Failed importing `net` library from kernel sources")
print(str(e))
diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py
index 01be3d9b9720..3e19b57ef5e0 100644
--- a/tools/testing/selftests/drivers/net/lib/py/env.py
+++ b/tools/testing/selftests/drivers/net/lib/py/env.py
@@ -1,12 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
import os
+import re
import time
from pathlib import Path
from lib.py import KsftSkipEx, KsftXfailEx
from lib.py import ksft_setup, wait_file
-from lib.py import cmd, ethtool, ip, CmdExitFailure
+from lib.py import cmd, ethtool, ip, rand_port, CmdExitFailure
from lib.py import NetNS, NetdevSimDev
+from lib.py import EthtoolFamily
from .remote import Remote
@@ -283,3 +285,70 @@ class NetDrvEpEnv(NetDrvEnvBase):
data.get('stats-block-usecs', 0) / 1000 / 1000
time.sleep(self._stats_settle_time)
+
+
+class MemPrvEnv(NetDrvEpEnv):
+ def __init__(self, src_path, rss=False, rss_num=1, **kwargs):
+ super().__init__(src_path, False, **kwargs)
+
+ self.ethnl = EthtoolFamily()
+ self.cleaned_up = False
+
+ channels = self.ethnl.channels_get({'header': {'dev-index': self.ifindex}})
+ self.channels = channels['combined-count']
+ if self.channels < 2:
+ raise KsftSkipEx('Test requires NETIF with at least 2 combined channels')
+
+ if rss and rss_num > self.channels - 1:
+ raise KsftSkipEx(f"Test with {rss_num} queues in RSS context requires NETIF with at least {rss_num + 1} combined channels")
+
+ self.port = rand_port()
+ rings = self.ethnl.rings_get({'header': {'dev-index': self.ifindex}})
+ self.rx_rings = rings['rx']
+ self.hds_thresh = rings.get('hds-thresh', 0)
+ self.ethnl.rings_set({'header': {'dev-index': self.ifindex},
+ 'tcp-data-split': 'enabled',
+ 'hds-thresh': 0,
+ 'rx': 64})
+
+ if rss:
+ self.target_queue = self.channels - rss_num
+ ethtool(f"-X {self.ifname} equal {self.target_queue}")
+ self.rss_ctx_id = self._create_rss_ctx(rss_num)
+ self.rule_id = self._set_rss_flow_rule()
+ else:
+ self.target_queue = self.channels - 1
+ ethtool(f"-X {self.ifname} equal {self.target_queue}")
+ self.rss_ctx_id = None
+ self.rule_id = self._set_flow_rule()
+
+ def __del__(self):
+ if self.cleaned_up:
+ return
+
+ ethtool(f"-N {self.ifname} delete {self.rule_id}")
+ if self.rss_ctx_id:
+ self.ethnl.rss_delete_act({'header': {'dev-index': self.ifindex},
+ 'context': self.rss_ctx_id})
+
+ ethtool(f"-X {self.ifname} default")
+ self.ethnl.rings_set({'header': {'dev-index': self.ifindex},
+ 'tcp-data-split': 'unknown',
+ 'hds-thresh': self.hds_thresh,
+ 'rx': self.rx_rings})
+ self.cleaned_up = True
+
+ def _set_flow_rule(self):
+ output = ethtool(f"-N {self.ifname} flow-type tcp6 dst-port {self.port} action {self.target_queue}").stdout
+ values = re.search(r'ID (\d+)', output).group(1)
+ return int(values)
+
+ def _set_rss_flow_rule(self):
+ output = ethtool(f"-N {self.ifname} flow-type tcp6 dst-port {self.port} context {self.rss_ctx_id}").stdout
+ values = re.search(r'ID (\d+)', output).group(1)
+ return int(values)
+
+ def _create_rss_ctx(self, num):
+ output = ethtool(f"-X {self.ifname} context new start {self.target_queue} equal {num}").stdout
+ values = re.search(r'New RSS context is (\d+)', output).group(1)
+ return int(values)
--
2.47.3
Powered by blists - more mailing lists