All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: daniel.zahka@gmail.com, willemdebruijn.kernel@gmail.com
Cc: edumazet@google.com, cratiu@nvidia.com, borisp@nvidia.com,
	kuniyu@google.com, netdev@vger.kernel.org,
	Jakub Kicinski <kuba@kernel.org>
Subject: [RFC net-next 6/6] selftests: drv-net: psp_steer: cover corner cases and races
Date: Sat, 22 Aug 2026 15:55:24 -0700	[thread overview]
Message-ID: <20260822225524.2328465-7-kuba@kernel.org> (raw)
In-Reply-To: <20260822225524.2328465-1-kuba@kernel.org>

Test a PSP cookie naming a queue which went away.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 .../selftests/drivers/net/psp_steer.py        | 80 ++++++++++++++++---
 1 file changed, 70 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/psp_steer.py b/tools/testing/selftests/drivers/net/psp_steer.py
index fac2d7532d61..f61479befcc0 100644
--- a/tools/testing/selftests/drivers/net/psp_steer.py
+++ b/tools/testing/selftests/drivers/net/psp_steer.py
@@ -6,17 +6,18 @@
 import errno
 import os
 import socket
+import time
 
 from lib.py import defer
 from lib.py import ksft_run, ksft_exit
-from lib.py import ksft_eq, ksft_ge, ksft_in, ksft_ne, ksft_raises
+from lib.py import ksft_eq, ksft_ge, ksft_in, ksft_lt, ksft_ne, ksft_raises
 from lib.py import CmdExitFailure, KsftSkipEx
 from lib.py import NetDrvEpEnv
 from lib.py import NetdevFamily, NlError, PSPFamily
 from lib.py import ethtool
 
 from psp_lib import close_conn, init_psp_dev, make_clr_conn, make_psp_conn, \
-    psp_txrx, remote_conn_steer, remote_dev_steer, spi_xchg
+    psp_txrx, remote_dev_steer, req_echo, spi_xchg
 from psp_lib import responder as psp_responder
 
 # Not exposed by the socket module
@@ -43,6 +44,8 @@ _VC_TX = 1 << 0
 _VC_RX = 1 << 1
 _VC_BOTH = _VC_TX | _VC_RX
 _VC_SIZE = 8
+_IDLE_TIME = 0.5
+_FALLBACK_QUEUE = 3
 
 
 def _require_steer(cfg):
@@ -138,18 +141,19 @@ _VC_SIZE = 8
     ethtool(f"-X {cfg.ifname} {ctx}weight {weights}")
 
 
-def _require_rss_steering(cfg):
-    """Skip unless the Rx queue actually follows the RSS table
+def _rss_steers(cfg):
+    """Does the Rx queue actually follow the RSS table?
 
-    Steering can only be shown to outrank RSS on a device where RSS has
-    a say in the first place - netdevsim, for one, ignores the table.
+    Steering can only be compared against RSS on a device where RSS has a
+    say in the first place - netdevsim, for one, ignores the table. Leaves
+    the table as it found it.
     """
     probe = cfg.rx_queue_cnt - 1
 
     try:
         _rss_pin(cfg, probe)
-    except CmdExitFailure as exc:
-        raise KsftSkipEx("Device does not support RSS table updates") from exc
+    except CmdExitFailure:
+        return False
     defer(ethtool, f"-X {cfg.ifname} default")
 
     with make_clr_conn(cfg) as s:
@@ -157,10 +161,22 @@ _VC_SIZE = 8
         landed = _rx_queue(cfg, s)
         close_conn(cfg, s)
 
-    if landed != probe:
+    ethtool(f"-X {cfg.ifname} default")
+    return landed == probe
+
+
+def _require_rss_steering(cfg):
+    """Skip unless the Rx queue follows the RSS table"""
+    if not _rss_steers(cfg):
         raise KsftSkipEx("Rx queue does not follow the RSS table")
 
 
+def _set_queue_cnt(cfg, cnt):
+    """Reconfigure the device, and re-read the NAPI ids it hands out"""
+    ethtool(f"-L {cfg.ifname} combined {cnt}")
+    _queue_info(cfg)
+
+
 def _ntuple_l3_rule(cfg, target):
     """Steer this host's traffic with an L3 only rule, and clean it up
 
@@ -378,6 +394,50 @@ _VC_SIZE = 8
         close_conn(cfg, s)
 
 
+def data_steer_stale_queue(cfg):
+    """ A cookie naming a queue which went away has to fall back to RSS """
+    _require_steer(cfg)
+    _require_queues(cfg, 8)
+    _enable_steer(cfg)
+
+    nq = cfg.rx_queue_cnt
+    rss = _rss_steers(cfg)
+    if rss:
+        # Point RSS at a queue of our choosing so that "it fell back to
+        # RSS" is a statement we can actually check. Deliberately not
+        # queue 0: plenty of devices use that as a default or error queue,
+        # and landing there would prove nothing - it would also be a
+        # thundering herd waiting to happen if every stale flow went there.
+        _rss_pin(cfg, _FALLBACK_QUEUE)
+
+    defer(_set_queue_cnt, cfg, nq)
+    defer(_force_tx_queue, cfg, -1)
+    _force_tx_queue(cfg, nq - 1)
+
+    with _psp_conn(cfg) as s:
+        qid, _ = _settled_rx_queue(cfg, s, 0)
+        ksft_eq(qid, nq - 1)
+
+        # Go properly idle first. A delayed ACK landing after the
+        # reconfiguration would carry a fresh request and teach the peer a
+        # live queue, and we would end up measuring nothing.
+        time.sleep(_IDLE_TIME)
+
+        # Take the queue away without telling the peer, which goes on
+        # asking for it in every cookie it sends.
+        _set_queue_cnt(cfg, nq - 1)
+
+        # One packet, so that our ACK cannot teach the peer a new queue
+        # before we get to look at where this one landed.
+        req_echo(cfg, s)
+        qid = _rx_queue(cfg, s)
+        close_conn(cfg, s)
+
+    ksft_lt(qid, nq - 1, comment="delivered to a queue which no longer exists")
+    if rss:
+        ksft_eq(qid, _FALLBACK_QUEUE, comment="stale request did not fall back to RSS")
+
+
 def _queue_info(cfg):
     """Map NAPI ids to Rx queue ids, and count the queues"""
     netnl = NetdevFamily()
@@ -398,7 +458,7 @@ _VC_SIZE = 8
 def main() -> None:
     """ Ksft boiler plate main """
 
-    with NetDrvEpEnv(__file__, queue_count=4) as cfg:
+    with NetDrvEpEnv(__file__, queue_count=8) as cfg:
         cfg.pspnl = PSPFamily()
         _queue_info(cfg)
 
-- 
2.55.0


  parent reply	other threads:[~2026-08-22 22:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-22 22:55 [RFC net-next 0/6] psp: use virt cookie as Rx steering hint Jakub Kicinski
2026-08-22 22:55 ` [RFC net-next 1/6] psp: steer Rx queues with the virtualization cookie Jakub Kicinski
2026-08-23 15:31   ` Daniel Zahka
2026-08-24 15:01     ` Jakub Kicinski
2026-08-24 15:09       ` Cosmin Ratiu
2026-08-24 15:19         ` Jakub Kicinski
2026-08-23 18:18   ` Willem de Bruijn
2026-08-22 22:55 ` [RFC net-next 2/6] netdevsim: support PSP VC based queue steering Jakub Kicinski
2026-08-22 22:55 ` [RFC net-next 3/6] selftests: drv-net: psp: move the PSP test plumbing into psp_lib.py Jakub Kicinski
2026-08-22 22:55 ` [RFC net-next 4/6] selftests: drv-net: psp_steer: test PSP VC based queue steering Jakub Kicinski
2026-08-22 22:55 ` [RFC net-next 5/6] selftests: drv-net: psp_steer: test where PSP steering sits in the Rx pipeline Jakub Kicinski
2026-08-22 22:55 ` Jakub Kicinski [this message]
2026-08-23 17:48 ` [RFC net-next 0/6] psp: use virt cookie as Rx steering hint Willem de Bruijn
2026-08-24 15:05   ` Cosmin Ratiu
2026-08-25  9:52     ` Cosmin Ratiu
2026-08-25 18:55       ` Jakub Kicinski
2026-08-24 15:11   ` Jakub Kicinski
2026-08-24 18:04     ` Willem de Bruijn

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=20260822225524.2328465-7-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=borisp@nvidia.com \
    --cc=cratiu@nvidia.com \
    --cc=daniel.zahka@gmail.com \
    --cc=edumazet@google.com \
    --cc=kuniyu@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=willemdebruijn.kernel@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.