[PATCH net-next v3 6/6] selftests: net: add rss_multiqueue test variant to iou-zcrx
From: Juanlu Herrero <hidden>
Date: 2026-07-22 20:42:29
Subsystem:
kernel selftest framework, networking drivers, the rest · Maintainers:
Shuah Khan, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Add a rss_multiqueue Python test variant that exercises multi-queue zero-copy receive on a single listening socket. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Juanlu Herrero <redacted> --- .../selftests/drivers/net/hw/iou-zcrx.py | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/iou-zcrx.py b/tools/testing/selftests/drivers/net/hw/iou-zcrx.py
index b7a225fe4beae..1f6083d8b05c4 100755
--- a/tools/testing/selftests/drivers/net/hw/iou-zcrx.py
+++ b/tools/testing/selftests/drivers/net/hw/iou-zcrx.py@@ -30,6 +30,12 @@ def create_rss_ctx(cfg): return int(values) +def create_rss_ctx_multi(cfg, start, count): + output = ethtool(f"-X {cfg.ifname} context new start {start} equal {count}").stdout + values = re.search(r'New RSS context is (\d+)', output).group(1) + return int(values) + + def set_flow_rule(cfg): output = ethtool(f"-N {cfg.ifname} flow-type tcp6 dst-port {cfg.port} action {cfg.target}").stdout values = re.search(r'ID (\d+)', output).group(1)
@@ -127,17 +133,55 @@ def _require_ntuple(cfg): defer(ethtool, f"-K {cfg.ifname} ntuple-filters off") +def rss_multiqueue(cfg): + channels = cfg.ethnl.channels_get({'header': {'dev-index': cfg.ifindex}}) + channels = channels['combined-count'] + if channels < 3: + raise KsftSkipEx('Test requires NETIF with at least 3 combined channels') + + rings = cfg.ethnl.rings_get({'header': {'dev-index': cfg.ifindex}}) + rx_rings = rings['rx'] + hds_thresh = rings.get('hds-thresh', 0) + + cfg.ethnl.rings_set({'header': {'dev-index': cfg.ifindex}, + 'tcp-data-split': 'enabled', + 'hds-thresh': 0, + 'rx': 64}) + defer(cfg.ethnl.rings_set, {'header': {'dev-index': cfg.ifindex}, + 'tcp-data-split': 'unknown', + 'hds-thresh': hds_thresh, + 'rx': rx_rings}) + defer(mp_clear_wait, cfg) + + cfg.num_threads = 2 + cfg.target = channels - cfg.num_threads + ethtool(f"-X {cfg.ifname} equal {cfg.target}") + defer(ethtool, f"-X {cfg.ifname} default") + + rss_ctx_id = create_rss_ctx_multi(cfg, cfg.target, cfg.num_threads) + defer(ethtool, f"-X {cfg.ifname} delete context {rss_ctx_id}") + + flow_rule_id = set_flow_rule_rss(cfg, rss_ctx_id) + defer(ethtool, f"-N {cfg.ifname} delete {flow_rule_id}") + + @ksft_variants([ KsftNamedVariant("single", single), KsftNamedVariant("rss", rss), + KsftNamedVariant("rss_multiqueue", rss_multiqueue), ]) def test_zcrx(cfg, setup) -> None: cfg.require_ipver('6') _require_ntuple(cfg) + cfg.num_threads = 1 + setup(cfg) - rx_cmd = f"{cfg.bin_local} -s -p {cfg.port} -i {cfg.ifname} -q {cfg.target}" - tx_cmd = f"{cfg.bin_remote} -c -h {cfg.addr_v['6']} -p {cfg.port} -l 12840" + + rx_cmd = (f"{cfg.bin_local} -s -p {cfg.port} -i {cfg.ifname} " + f"-q {cfg.target} -t {cfg.num_threads}") + tx_cmd = (f"{cfg.bin_remote} -c -h {cfg.addr_v['6']} -p {cfg.port} " + f"-l 12840 -t {cfg.num_threads}") with bkg(rx_cmd, exit_wait=True): wait_port_listen(cfg.port, proto="tcp") cmd(tx_cmd, host=cfg.remote)
--
2.53.0-Meta