Thread (10 messages) flat view 10 messages, 3 authors, 3d ago

[RFC net-next 6/6] selftests: drv-net: measure devmem performance with kperf

From: Stanislav Fomichev <hidden>
Date: 2026-09-16 19:04:23
Subsystem: kernel selftest framework, networking drivers, the rest · Maintainers: Shuah Khan, Shuah Khan, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Add devmem performance test using kperf and SystemMonitor.

Tested on two mlx5 hosts. Benchmark metric output:

  # # ktap-metric-policy-json: {"name":"throughput","regression":{"better":"higher","compare":"p50","relative_tolerance":0.05},"summarize":"distribution"}
  # # ktap-metric-policy-json: {"name":"tcp.retransmits","summarize":"max"}
  # # ktap-metric-json: {"host":"remote","name":"throughput","shape":"scalar","time":20.457972,"value":321.225}
  # # ktap-metric-json: {"host":"remote","name":"tcp.retransmits","shape":"scalar","time":20.457989,"value":903.0}
  # # ktap-metric-json: {"host":"local","name":"throughput","shape":"scalar","time":20.457993,"value":321.16499999999996}
  # # ktap-metric-json: {"host":"local","name":"tcp.retransmits","shape":"scalar","time":20.457998,"value":0.0}
  # ok 6 devmem.check_kperf
  # # Totals: pass:5 fail:0 xfail:0 xpass:0 skip:1 error:0

Note this is still CUDA (because 4K udmabuf needs my posted genpool
changes), will move to udmabuf once the genpoll stuff lands.

Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
 .../selftests/drivers/net/hw/devmem.py        | 70 ++++++++++++++++++-
 1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/devmem.py b/tools/testing/selftests/drivers/net/hw/devmem.py
index 82c11ffc4add..4795b33e5efc 100755
--- a/tools/testing/selftests/drivers/net/hw/devmem.py
+++ b/tools/testing/selftests/drivers/net/hw/devmem.py
@@ -3,8 +3,9 @@
 
 from os import path
 from devmem_lib import (setup_test, run_rx, run_tx, run_tx_chunks, run_rx_hds,
-                        run_rx_large_niov)
-from lib.py import ksft_run, ksft_exit, ksft_disruptive
+                        run_rx_large_niov, require_devmem)
+from lib.py import (defer, EthtoolFamily, KperfRunner, ksft_run, SystemMonitor,
+                    ksft_exit, ksft_disruptive)
 from lib.py import NetDrvEpEnv
 
 
@@ -36,12 +37,75 @@ from lib.py import NetDrvEpEnv
     run_rx_large_niov(cfg)
 
 
+@ksft_disruptive
+def check_kperf(cfg) -> None:
+    """Measure CUDA-backed devmem RX performance with kperf."""
+    cfg.require_nsim(False)
+
+    kperf = KperfRunner(cfg)
+
+    dmabuf_size = 2048
+    # once udmabuf works well with 4K:
+    # dmabuf_size = 64
+    # if cmd("test -c /dev/udmabuf", fail=False).ret:
+    #     raise KsftSkipEx("Test requires /dev/udmabuf")
+    # size_limit = cmd("cat /sys/module/udmabuf/parameters/size_limit_mb",
+    #                  fail=False)
+    # if size_limit.ret == 0 and int(size_limit.stdout) < dmabuf_size:
+    #     raise KsftSkipEx(
+    #         f"Test requires a {dmabuf_size} MiB udmabuf size limit")
+
+    require_devmem(cfg)
+
+    ethnl = EthtoolFamily()
+    rings = ethnl.rings_get({"header": {"dev-index": cfg.ifindex}})
+    defer(ethnl.rings_set, {
+        "header": {"dev-index": cfg.ifindex},
+        "tcp-data-split": rings.get("tcp-data-split", "unknown"),
+        "rx": rings["rx"],
+    })
+    ethnl.rings_set({
+        "header": {"dev-index": cfg.ifindex},
+        "tcp-data-split": "enabled",
+        "rx": rings["rx-max"],
+    })
+
+    rss = ethnl.rss_get({"header": {"dev-index": cfg.ifindex}})
+    defer(ethnl.rss_set, {
+        "header": {"dev-index": cfg.ifindex},
+        "indir": rss["indir"],
+    })
+
+    devmem_args = [
+        "--time", "15",
+        "--num-connections", "4",
+        "--read-size", str(64 << 20),
+        "--write-size", str(64 << 20),
+        "--pin-off", "4",
+        "--num-rx-queues", "4",
+        "--dmabuf-rx-size-mb", str(dmabuf_size),
+        "--dmabuf-tx-size-mb", str(dmabuf_size),
+        "--validate", "no",
+        "--devmem-rx",
+        "--devmem-tx",
+        "--devmem-rx-memory", "cuda",
+        "--devmem-tx-memory", "cuda",
+        "--devmem-src-dev", "0000:4e:00",
+        "--devmem-dst-dev", "0000:4e:00",
+    ]
+
+    # The remote source uses CUDA TX and the local destination uses CUDA RX.
+    with kperf:
+        with SystemMonitor(cfg):
+            kperf.run(client_args=devmem_args)
+
+
 def main() -> None:
     """Run the devmem test cases."""
     with NetDrvEpEnv(__file__) as cfg:
         setup_test(cfg, path.abspath(path.dirname(__file__) + "/ncdevmem"))
         ksft_run([check_rx, check_tx, check_tx_chunks, check_rx_hds,
-                  check_rx_large_niov],
+                  check_rx_large_niov, check_kperf],
                  args=(cfg,))
     ksft_exit()
 
-- 
2.53.0-Meta
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help