* [PATCH net-next v7 0/3] selftests: drv-net: convert so_txtime to drv-net
From: Willem de Bruijn @ 2026-05-04 17:38 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, edumazet, pabeni, horms, linux-kselftest, shuah,
Willem de Bruijn
From: Willem de Bruijn <willemb@google.com>
In preparation for extending to pacing hardware offload, convert the
so_txtime.sh test to a drv-net test that can be run against netdevsim
and real hardware.
Two preparatory patches
1. support negative tests, where tests are expected to fail
2. add a tc helper
See individual patches for details and detailed changelog
Previous versions:
v6: https://lore.kernel.org/netdev/20260430132820.1944517-1-willemdebruijn.kernel@gmail.com/
v5: https://lore.kernel.org/netdev/20260427201640.294694-1-willemdebruijn.kernel@gmail.com/
v4: https://lore.kernel.org/netdev/20260409164238.661091-1-willemdebruijn.kernel@gmail.com/
v3: https://lore.kernel.org/netdev/20260406025020.1636895-1-willemdebruijn.kernel@gmail.com/
v2: https://lore.kernel.org/netdev/20260405014458.1038165-1-willemdebruijn.kernel@gmail.com/
v1: https://lore.kernel.org/netdev/20260403175047.152646-1-willemdebruijn.kernel@gmail.com/
Willem de Bruijn (3):
selftests: net: py: support cmd verifying expected failure
selftests: net: py: add tc utility
selftests: drv-net: convert so_txtime to drv-net
.../testing/selftests/drivers/net/.gitignore | 1 +
tools/testing/selftests/drivers/net/Makefile | 2 +
tools/testing/selftests/drivers/net/config | 2 +
.../selftests/drivers/net/lib/py/__init__.py | 5 +-
.../selftests/{ => drivers}/net/so_txtime.c | 25 +++-
.../selftests/drivers/net/so_txtime.py | 96 +++++++++++++++
tools/testing/selftests/net/.gitignore | 1 -
tools/testing/selftests/net/Makefile | 2 -
.../testing/selftests/net/lib/py/__init__.py | 4 +-
tools/testing/selftests/net/lib/py/utils.py | 51 ++++++--
tools/testing/selftests/net/so_txtime.sh | 110 ------------------
11 files changed, 166 insertions(+), 133 deletions(-)
rename tools/testing/selftests/{ => drivers}/net/so_txtime.c (96%)
create mode 100755 tools/testing/selftests/drivers/net/so_txtime.py
delete mode 100755 tools/testing/selftests/net/so_txtime.sh
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply
* [PATCH net-next v7 1/3] selftests: net: py: support cmd verifying expected failure
From: Willem de Bruijn @ 2026-05-04 17:38 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, edumazet, pabeni, horms, linux-kselftest, shuah,
Willem de Bruijn
In-Reply-To: <20260504174056.565319-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemb@google.com>
Support negative tests, where cmd raises an exception if the command
succeeded.
Add optional argument expect_fail to cmd and bkg. Where fail fails the
test on unexpected error, expect_fail fails it on unexpected success.
Both fail on negative return code. Python subprocess may set a
negative return code on process crash or timeout. Those are never
anticipated failures.
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
In this design fail and expect_fail are two complementary tests.
If both are set to true, an exception would always be raised.
This is contrast to the previous approach, where fail enables
fail_on_unexpected_returncode and expect_fail modifies what that
unexpected_returncode value range is.
---
v6 -> v7
- convert from 'verify_failed' value for fail, to separate variable
v4 -> v5
- initial version of standalone patch
---
tools/testing/selftests/net/lib/py/utils.py | 39 +++++++++++++++------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index 6c44a3d2bbf7..b68d4607114d 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -23,6 +23,10 @@ class CmdExitFailure(Exception):
self.cmd = cmd_obj
+class CmdExitZeroFailure(CmdExitFailure):
+ """ Command succeeded (returned zero exit code), but expected failure. """
+
+
def fd_read_timeout(fd, timeout):
rlist, _, _ = select.select([fd], [], [], timeout)
if rlist:
@@ -39,8 +43,9 @@ class cmd:
Use bkg() instead to run a command in the background.
"""
- def __init__(self, comm, shell=None, fail=True, ns=None, background=False,
- host=None, timeout=5, ksft_ready=None, ksft_wait=None):
+ def __init__(self, comm, shell=None, fail=True, expect_fail=False, ns=None,
+ background=False, host=None, timeout=5, ksft_ready=None,
+ ksft_wait=None):
if ns:
comm = f'ip netns exec {ns} ' + comm
@@ -88,7 +93,8 @@ class cmd:
self._process_terminate(terminate=terminate, timeout=1)
raise CmdInitFailure("Did not receive ready message", self)
if not background:
- self.process(terminate=False, fail=fail, timeout=timeout)
+ self.process(terminate=False, fail=fail, expect_fail=expect_fail,
+ timeout=timeout)
def _process_terminate(self, terminate, timeout):
if terminate:
@@ -102,7 +108,7 @@ class cmd:
return stdout, stderr
- def process(self, terminate=True, fail=None, timeout=5):
+ def process(self, terminate=True, fail=None, expect_fail=False, timeout=5):
if fail is None:
fail = not terminate
@@ -111,10 +117,19 @@ class cmd:
stdout, stderr = self._process_terminate(terminate=terminate,
timeout=timeout)
- if self.proc.returncode != 0 and fail:
+
+ # Fail on unexpected test failure if fail.
+ # Fail on unexpected test success if expect_fail.
+ # Fail on negative returncode if either:
+ # Set by subprocess on crash or signal, this is never expected failure.
+ if (self.proc.returncode != 0 and fail or
+ (self.proc.returncode < 0 and expect_fail)):
if len(stderr) > 0 and stderr[-1] == "\n":
stderr = stderr[:-1]
raise CmdExitFailure("Command failed", self)
+ elif self.proc.returncode == 0 and expect_fail:
+ raise CmdExitZeroFailure("Command succeeded (expected fail)", self)
+
def __repr__(self):
def str_fmt(name, s):
@@ -157,14 +172,17 @@ class bkg(cmd):
with bkg("my_binary", ksft_wait=5):
"""
- def __init__(self, comm, shell=None, fail=None, ns=None, host=None,
- exit_wait=False, ksft_ready=None, ksft_wait=None):
+ def __init__(self, comm, shell=None, fail=None, expect_fail=None,
+ ns=None, host=None, exit_wait=False, ksft_ready=None,
+ ksft_wait=None):
super().__init__(comm, background=True,
- shell=shell, fail=fail, ns=ns, host=host,
- ksft_ready=ksft_ready, ksft_wait=ksft_wait)
+ shell=shell, fail=fail, expect_fail=expect_fail,
+ ns=ns, host=host, ksft_ready=ksft_ready,
+ ksft_wait=ksft_wait)
self.terminate = not exit_wait and not ksft_wait
self._exit_wait = exit_wait
self.check_fail = fail
+ self.expect_fail = expect_fail
if shell and self.terminate:
print("# Warning: combining shell and terminate is risky!")
@@ -179,7 +197,8 @@ class bkg(cmd):
# since forcing termination silences failures with fail=None
if self.proc.poll() is None:
terminate = terminate or (self._exit_wait and ex_type is not None)
- return self.process(terminate=terminate, fail=self.check_fail)
+ return self.process(terminate=terminate, fail=self.check_fail,
+ expect_fail=self.expect_fail)
GLOBAL_DEFER_QUEUE = []
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH net-next v7 2/3] selftests: net: py: add tc utility
From: Willem de Bruijn @ 2026-05-04 17:38 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, edumazet, pabeni, horms, linux-kselftest, shuah,
Willem de Bruijn
In-Reply-To: <20260504174056.565319-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemb@google.com>
Add a wrapper similar to existing ip, ethtool, ... commands.
Tc takes a slightly different syntax. Account for that.
The first user is the next patch in this series, converting so_txtime
to drv-net. Pacing offload is supported by selected qdiscs only.
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
.../testing/selftests/drivers/net/lib/py/__init__.py | 5 +++--
tools/testing/selftests/net/lib/py/__init__.py | 4 ++--
tools/testing/selftests/net/lib/py/utils.py | 12 +++++++++++-
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py
index 2b5ec0505672..09aac4ce67bc 100644
--- a/tools/testing/selftests/drivers/net/lib/py/__init__.py
+++ b/tools/testing/selftests/drivers/net/lib/py/__init__.py
@@ -23,7 +23,8 @@ try:
NlError, RtnlFamily, DevlinkFamily, PSPFamily, Netlink
from net.lib.py import CmdExitFailure
from net.lib.py import bkg, cmd, bpftool, bpftrace, defer, ethtool, \
- fd_read_timeout, ip, rand_port, rand_ports, wait_port_listen, wait_file
+ fd_read_timeout, ip, rand_port, rand_ports, tc, wait_port_listen, \
+ wait_file
from net.lib.py import bpf_map_set, bpf_map_dump, bpf_prog_map_ids
from net.lib.py import KsftSkipEx, KsftFailEx, KsftXfailEx
from net.lib.py import ksft_disruptive, ksft_exit, ksft_pr, ksft_run, \
@@ -36,7 +37,7 @@ try:
"NlError", "RtnlFamily", "DevlinkFamily", "PSPFamily", "Netlink",
"CmdExitFailure",
"bkg", "cmd", "bpftool", "bpftrace", "defer", "ethtool",
- "fd_read_timeout", "ip", "rand_port", "rand_ports",
+ "fd_read_timeout", "ip", "rand_port", "rand_ports", "tc",
"wait_port_listen", "wait_file",
"bpf_map_set", "bpf_map_dump", "bpf_prog_map_ids",
"KsftSkipEx", "KsftFailEx", "KsftXfailEx",
diff --git a/tools/testing/selftests/net/lib/py/__init__.py b/tools/testing/selftests/net/lib/py/__init__.py
index 7c81d86a7e97..64a8c1ed4950 100644
--- a/tools/testing/selftests/net/lib/py/__init__.py
+++ b/tools/testing/selftests/net/lib/py/__init__.py
@@ -14,7 +14,7 @@ from .netns import NetNS, NetNSEnter
from .nsim import NetdevSim, NetdevSimDev
from .utils import CmdExitFailure, fd_read_timeout, cmd, bkg, defer, \
bpftool, ip, ethtool, bpftrace, rand_port, rand_ports, wait_port_listen, \
- wait_file, tool
+ wait_file, tool, tc
from .bpf import bpf_map_set, bpf_map_dump, bpf_prog_map_ids
from .ynl import NlError, NlctrlFamily, YnlFamily, \
EthtoolFamily, NetdevFamily, RtnlFamily, RtnlAddrFamily
@@ -29,7 +29,7 @@ __all__ = ["KSRC",
"NetNS", "NetNSEnter",
"CmdExitFailure", "fd_read_timeout", "cmd", "bkg", "defer",
"bpftool", "ip", "ethtool", "bpftrace", "rand_port", "rand_ports",
- "wait_port_listen", "wait_file", "tool",
+ "wait_port_listen", "wait_file", "tool", "tc",
"bpf_map_set", "bpf_map_dump", "bpf_prog_map_ids",
"NetdevSim", "NetdevSimDev",
"NetshaperFamily", "DevlinkFamily", "PSPFamily", "NlError",
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index b68d4607114d..be9408a77168 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -239,7 +239,10 @@ class defer:
def tool(name, args, json=None, ns=None, host=None):
cmd_str = name + ' '
if json:
- cmd_str += '--json '
+ if name == 'tc':
+ cmd_str += '-json '
+ else:
+ cmd_str += '--json '
cmd_str += args
cmd_obj = cmd(cmd_str, ns=ns, host=host)
if json:
@@ -257,6 +260,13 @@ def ip(args, json=None, ns=None, host=None):
return tool('ip', args, json=json, host=host)
+def tc(args, json=None, ns=None, host=None):
+ """ Helper to call tc with standard set of optional args. """
+ if ns:
+ args = f'-netns {ns} ' + args
+ return tool('tc', args, json=json, host=host)
+
+
def ethtool(args, json=None, ns=None, host=None):
return tool('ethtool', args, json=json, ns=ns, host=host)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* Re: [PATCH net-next] e1000e: ethtool: add get_channels support
From: Joe Damato @ 2026-05-04 17:41 UTC (permalink / raw)
To: Jon Kohler
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, intel-wired-lan,
netdev, linux-kernel
In-Reply-To: <20260504154823.2535612-1-jon@nutanix.com>
On Mon, May 04, 2026 at 08:48:23AM -0700, Jon Kohler wrote:
> e1000e hardware supports a single RX/TX queue pair, add basic support
> for ethtool -l (i.e. get_channels), so that callers indeed see a single
> queue.
>
> Signed-off-by: Jon Kohler <jon@nutanix.com>
> ---
> drivers/net/ethernet/intel/e1000e/ethtool.c | 26 +++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
Reviewed-by: Joe Damato <joe@dama.to>
^ permalink raw reply
* [PATCH net-next v7 3/3] selftests: drv-net: convert so_txtime to drv-net
From: Willem de Bruijn @ 2026-05-04 17:38 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, edumazet, pabeni, horms, linux-kselftest, shuah,
Willem de Bruijn
In-Reply-To: <20260504174056.565319-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemb@google.com>
In preparation for extending to pacing hardware offload, convert the
so_txtime.sh test to a drv-net test that can be run against netdevsim
and real hardware.
Also update so_txtime.c to not exit on first failure, but run to
completion and report exit code there. This helps with debugging
unexpected results, especially when processing multiple packets,
as happens in the "reverse_order" testcase.
Signed-off-by: Willem de Bruijn <willemb@google.com>
----
v6 -> v7
- update test to use new argument expect_fail
- v6 received Reviewed-by, but dropped due to above (minor) change
v5 -> v6
- fix order in tools/testing/selftests/drivers/net/config
v4 -> v5
- move qdisc setup/restore into each test
- add tc to utils.py (separate patch)
- test expected failure (separate patch)
- fix pylint
- convert fail to pass for timing errors if KSFT_MACHINE_SLOW
(cmd does not special case KSFT_SKIP process returncode yet)
Responses to sashiko review
- The test converts per packet failure to errors, to continue
testing other packets, but other error() cases are not in scope.
- The test starts sender and receiver at an absolute future time,
like the original test. This assumes ~msec scale sync'ed clocks.
- The tc qdisc replace command works fine with noqueue. Tested
manually.
v3 -> v4
- restore original qdisc after test
- drop unnecessary underscore in tap test names
v2 -> v3
- Makefile: so_txtime from YNL_GEN_FILES to TEST_GEN_FILES (Sashiko, NIPA)
v1 -> v2
- move so_txtime.c for net/lib to drivers/net (Jakub)
- fix drivers/net/config order (Jakub)
- detect passing when failure is expected (Jakub, Sashiko)
- pass pylint --disable=R (Jakub)
- only call ksft_run once (Jakub)
- do not sleep if waiting time is negative (Sashiko)
- add \n when converting error() to fprintf() (Sashiko)
- 4 space indentation, instead of 2 space
- increase sync delay from 100 to 200ms, to fix rare vng flakes
---
.../testing/selftests/drivers/net/.gitignore | 1 +
tools/testing/selftests/drivers/net/Makefile | 2 +
tools/testing/selftests/drivers/net/config | 2 +
.../selftests/{ => drivers}/net/so_txtime.c | 25 +++-
.../selftests/drivers/net/so_txtime.py | 96 +++++++++++++++
tools/testing/selftests/net/.gitignore | 1 -
tools/testing/selftests/net/Makefile | 2 -
tools/testing/selftests/net/so_txtime.sh | 110 ------------------
8 files changed, 121 insertions(+), 118 deletions(-)
rename tools/testing/selftests/{ => drivers}/net/so_txtime.c (96%)
create mode 100755 tools/testing/selftests/drivers/net/so_txtime.py
delete mode 100755 tools/testing/selftests/net/so_txtime.sh
diff --git a/tools/testing/selftests/drivers/net/.gitignore b/tools/testing/selftests/drivers/net/.gitignore
index 585ecb4d5dc4..e5314ce4bb2d 100644
--- a/tools/testing/selftests/drivers/net/.gitignore
+++ b/tools/testing/selftests/drivers/net/.gitignore
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
napi_id_helper
psp_responder
+so_txtime
diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
index b72080c6d06b..d5bf4cb638a8 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -7,6 +7,7 @@ TEST_INCLUDES := $(wildcard lib/py/*.py) \
TEST_GEN_FILES := \
napi_id_helper \
+ so_txtime \
# end of TEST_GEN_FILES
TEST_PROGS := \
@@ -21,6 +22,7 @@ TEST_PROGS := \
queues.py \
ring_reconfig.py \
shaper.py \
+ so_txtime.py \
stats.py \
xdp.py \
# end of TEST_PROGS
diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config
index fd16994366f4..2309109a94ec 100644
--- a/tools/testing/selftests/drivers/net/config
+++ b/tools/testing/selftests/drivers/net/config
@@ -8,5 +8,7 @@ CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETCONSOLE_EXTENDED_LOG=y
CONFIG_NETDEVSIM=m
+CONFIG_NET_SCH_ETF=m
+CONFIG_NET_SCH_FQ=m
CONFIG_VLAN_8021Q=m
CONFIG_XDP_SOCKETS=y
diff --git a/tools/testing/selftests/net/so_txtime.c b/tools/testing/selftests/drivers/net/so_txtime.c
similarity index 96%
rename from tools/testing/selftests/net/so_txtime.c
rename to tools/testing/selftests/drivers/net/so_txtime.c
index b76df1efc2ef..b6930883569b 100644
--- a/tools/testing/selftests/net/so_txtime.c
+++ b/tools/testing/selftests/drivers/net/so_txtime.c
@@ -33,6 +33,8 @@
#include <unistd.h>
#include <poll.h>
+#include "kselftest.h"
+
static int cfg_clockid = CLOCK_TAI;
static uint16_t cfg_port = 8000;
static int cfg_variance_us = 4000;
@@ -43,6 +45,8 @@ static bool cfg_rx;
static uint64_t glob_tstart;
static uint64_t tdeliver_max;
+static int errors;
+
/* encode one timed transmission (of a 1B payload) */
struct timed_send {
char data;
@@ -131,13 +135,15 @@ static void do_recv_one(int fdr, struct timed_send *ts)
fprintf(stderr, "payload:%c delay:%lld expected:%lld (us)\n",
rbuf[0], (long long)tstop, (long long)texpect);
- if (rbuf[0] != ts->data)
- error(1, 0, "payload mismatch. expected %c", ts->data);
+ if (rbuf[0] != ts->data) {
+ fprintf(stderr, "payload mismatch. expected %c\n", ts->data);
+ errors++;
+ }
if (llabs(tstop - texpect) > cfg_variance_us) {
fprintf(stderr, "exceeds variance (%d us)\n", cfg_variance_us);
if (!getenv("KSFT_MACHINE_SLOW"))
- exit(1);
+ errors++;
}
}
@@ -255,8 +261,12 @@ static void start_time_wait(void)
return;
now = gettime_ns(CLOCK_REALTIME);
- if (cfg_start_time_ns < now)
+ if (cfg_start_time_ns < now) {
+ fprintf(stderr, "FAIL: start time already passed\n");
+ if (!getenv("KSFT_MACHINE_SLOW"))
+ errors++;
return;
+ }
err = usleep((cfg_start_time_ns - now) / 1000);
if (err)
@@ -513,5 +523,10 @@ int main(int argc, char **argv)
else
do_test_tx((void *)&cfg_src_addr, cfg_alen);
- return 0;
+ if (errors) {
+ fprintf(stderr, "FAIL: %d errors\n", errors);
+ return KSFT_FAIL;
+ }
+
+ return KSFT_PASS;
}
diff --git a/tools/testing/selftests/drivers/net/so_txtime.py b/tools/testing/selftests/drivers/net/so_txtime.py
new file mode 100755
index 000000000000..5b54ce76dff4
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/so_txtime.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""Regression tests for the SO_TXTIME interface.
+
+Test delivery time in FQ and ETF qdiscs.
+"""
+
+import time
+
+from lib.py import ksft_exit, ksft_run, ksft_variants
+from lib.py import KsftNamedVariant, KsftSkipEx
+from lib.py import NetDrvEpEnv, bkg, cmd, defer, tc
+
+
+def test_so_txtime(cfg, clockid, ipver, args_tx, args_rx, expect_success):
+ """Main function. Run so_txtime as sender and receiver."""
+ bin_path = cfg.test_dir / "so_txtime"
+
+ tstart = time.time_ns() + 200_000_000
+
+ cmd_addr = f"-S {cfg.addr_v[ipver]} -D {cfg.remote_addr_v[ipver]}"
+ cmd_base = f"{bin_path} -{ipver} -c {clockid} -t {tstart} {cmd_addr}"
+ cmd_rx = f"{cmd_base} {args_rx} -r"
+ cmd_tx = f"{cmd_base} {args_tx}"
+
+ with bkg(cmd_rx, host=cfg.remote, fail=expect_success,
+ expect_fail=(not expect_success), exit_wait=True):
+ cmd(cmd_tx)
+
+
+def _qdisc_setup(ifname, qdisc, optargs=""):
+ """Replace root qdisc. Restore the original after the test.
+
+ If the original is mq, children will be of type default_qdisc.
+ """
+ orig = tc(f"qdisc show dev {ifname} root", json=True)[0].get("kind", None)
+ defer(tc, f"qdisc replace dev {ifname} root {orig}")
+ tc(f"qdisc replace dev {ifname} root {qdisc} {optargs}")
+
+
+def _test_variants_mono():
+ for ipver in ["4", "6"]:
+ for testcase in [
+ ["no_delay", "a,-1", "a,-1"],
+ ["zero_delay", "a,0", "a,0"],
+ ["one_pkt", "a,10", "a,10"],
+ ["in_order", "a,10,b,20", "a,10,b,20"],
+ ["reverse_order", "a,20,b,10", "b,20,a,20"],
+ ]:
+ name = f"v{ipver}_{testcase[0]}"
+ yield KsftNamedVariant(name, ipver, testcase[1], testcase[2])
+
+
+@ksft_variants(_test_variants_mono())
+def test_so_txtime_mono(cfg, ipver, args_tx, args_rx):
+ """Run all variants of monotonic (fq) tests."""
+ _qdisc_setup(cfg.ifname, "fq")
+ test_so_txtime(cfg, "mono", ipver, args_tx, args_rx, True)
+
+
+def _test_variants_etf():
+ for ipver in ["4", "6"]:
+ for testcase in [
+ ["no_delay", "a,-1", "a,-1", False],
+ ["zero_delay", "a,0", "a,0", False],
+ ["one_pkt", "a,10", "a,10", True],
+ ["in_order", "a,10,b,20", "a,10,b,20", True],
+ ["reverse_order", "a,20,b,10", "b,10,a,20", True],
+ ]:
+ name = f"v{ipver}_{testcase[0]}"
+ yield KsftNamedVariant(
+ name, ipver, testcase[1], testcase[2], testcase[3]
+ )
+
+
+@ksft_variants(_test_variants_etf())
+def test_so_txtime_etf(cfg, ipver, args_tx, args_rx, expect_fail):
+ """Run all variants of etf tests."""
+ try:
+ _qdisc_setup(cfg.ifname, "etf", "clockid CLOCK_TAI delta 400000")
+ except Exception as e:
+ raise KsftSkipEx("tc does not support qdisc etf. skipping") from e
+
+ test_so_txtime(cfg, "tai", ipver, args_tx, args_rx, expect_fail)
+
+
+def main() -> None:
+ """Boilerplate ksft main."""
+ with NetDrvEpEnv(__file__) as cfg:
+ ksft_run([test_so_txtime_mono, test_so_txtime_etf], args=(cfg,))
+ ksft_exit()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore
index 97ad4d551d44..02ad4c99a2b4 100644
--- a/tools/testing/selftests/net/.gitignore
+++ b/tools/testing/selftests/net/.gitignore
@@ -40,7 +40,6 @@ skf_net_off
socket
so_incoming_cpu
so_netns_cookie
-so_txtime
so_rcv_listener
stress_reuseport_listen
tap
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index a275ed584026..d53670c0d7a2 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -83,7 +83,6 @@ TEST_PROGS := \
rxtimestamp.sh \
sctp_vrf.sh \
skf_net_off.sh \
- so_txtime.sh \
srv6_end_dt46_l3vpn_test.sh \
srv6_end_dt4_l3vpn_test.sh \
srv6_end_dt6_l3vpn_test.sh \
@@ -157,7 +156,6 @@ TEST_GEN_FILES := \
skf_net_off \
so_netns_cookie \
so_rcv_listener \
- so_txtime \
socket \
stress_reuseport_listen \
tcp_fastopen_backup_key \
diff --git a/tools/testing/selftests/net/so_txtime.sh b/tools/testing/selftests/net/so_txtime.sh
deleted file mode 100755
index 5e861ad32a42..000000000000
--- a/tools/testing/selftests/net/so_txtime.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/bash
-# SPDX-License-Identifier: GPL-2.0
-#
-# Regression tests for the SO_TXTIME interface
-
-set -e
-
-readonly ksft_skip=4
-readonly DEV="veth0"
-readonly BIN="./so_txtime"
-
-readonly RAND="$(mktemp -u XXXXXX)"
-readonly NSPREFIX="ns-${RAND}"
-readonly NS1="${NSPREFIX}1"
-readonly NS2="${NSPREFIX}2"
-
-readonly SADDR4='192.168.1.1'
-readonly DADDR4='192.168.1.2'
-readonly SADDR6='fd::1'
-readonly DADDR6='fd::2'
-
-cleanup() {
- ip netns del "${NS2}"
- ip netns del "${NS1}"
-}
-
-trap cleanup EXIT
-
-# Create virtual ethernet pair between network namespaces
-ip netns add "${NS1}"
-ip netns add "${NS2}"
-
-ip link add "${DEV}" netns "${NS1}" type veth \
- peer name "${DEV}" netns "${NS2}"
-
-# Bring the devices up
-ip -netns "${NS1}" link set "${DEV}" up
-ip -netns "${NS2}" link set "${DEV}" up
-
-# Set fixed MAC addresses on the devices
-ip -netns "${NS1}" link set dev "${DEV}" address 02:02:02:02:02:02
-ip -netns "${NS2}" link set dev "${DEV}" address 06:06:06:06:06:06
-
-# Add fixed IP addresses to the devices
-ip -netns "${NS1}" addr add 192.168.1.1/24 dev "${DEV}"
-ip -netns "${NS2}" addr add 192.168.1.2/24 dev "${DEV}"
-ip -netns "${NS1}" addr add fd::1/64 dev "${DEV}" nodad
-ip -netns "${NS2}" addr add fd::2/64 dev "${DEV}" nodad
-
-run_test() {
- local readonly IP="$1"
- local readonly CLOCK="$2"
- local readonly TXARGS="$3"
- local readonly RXARGS="$4"
-
- if [[ "${IP}" == "4" ]]; then
- local readonly SADDR="${SADDR4}"
- local readonly DADDR="${DADDR4}"
- elif [[ "${IP}" == "6" ]]; then
- local readonly SADDR="${SADDR6}"
- local readonly DADDR="${DADDR6}"
- else
- echo "Invalid IP version ${IP}"
- exit 1
- fi
-
- local readonly START="$(date +%s%N --date="+ 0.1 seconds")"
-
- ip netns exec "${NS2}" "${BIN}" -"${IP}" -c "${CLOCK}" -t "${START}" -S "${SADDR}" -D "${DADDR}" "${RXARGS}" -r &
- ip netns exec "${NS1}" "${BIN}" -"${IP}" -c "${CLOCK}" -t "${START}" -S "${SADDR}" -D "${DADDR}" "${TXARGS}"
- wait "$!"
-}
-
-do_test() {
- run_test $@
- [ $? -ne 0 ] && ret=1
-}
-
-do_fail_test() {
- run_test $@
- [ $? -eq 0 ] && ret=1
-}
-
-ip netns exec "${NS1}" tc qdisc add dev "${DEV}" root fq
-set +e
-ret=0
-do_test 4 mono a,-1 a,-1
-do_test 6 mono a,0 a,0
-do_test 6 mono a,10 a,10
-do_test 4 mono a,10,b,20 a,10,b,20
-do_test 6 mono a,20,b,10 b,20,a,20
-
-if ip netns exec "${NS1}" tc qdisc replace dev "${DEV}" root etf clockid CLOCK_TAI delta 400000; then
- do_fail_test 4 tai a,-1 a,-1
- do_fail_test 6 tai a,0 a,0
- do_test 6 tai a,10 a,10
- do_test 4 tai a,10,b,20 a,10,b,20
- do_test 6 tai a,20,b,10 b,10,a,20
-else
- echo "tc ($(tc -V)) does not support qdisc etf. skipping"
- [ $ret -eq 0 ] && ret=$ksft_skip
-fi
-
-if [ $ret -eq 0 ]; then
- echo OK. All tests passed
-elif [[ $ret -ne $ksft_skip && -n "$KSFT_MACHINE_SLOW" ]]; then
- echo "Ignoring errors due to slow environment" 1>&2
- ret=0
-fi
-exit $ret
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Eric Biggers @ 2026-05-04 17:39 UTC (permalink / raw)
To: Jon Kohler
Cc: linux-crypto@vger.kernel.org, Herbert Xu,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <4D424F50-7E9F-4B1F-AE9C-86D8526284E6@nutanix.com>
On Mon, May 04, 2026 at 02:39:12PM +0000, Jon Kohler wrote:
> > On Apr 29, 2026, at 9:15 PM, Eric Biggers <ebiggers@kernel.org> wrote:
> >
> > AF_ALG is almost completely unnecessary, and it exposes a massive attack
> > surface that hasn't been standing up to modern vulnerability discovery
> > tools. The latest one even has its own website, providing a small
> > Python script that reliably roots most Linux distros: https://copy.fail/
> >
> > This isn't sustainable, especially as LLMs have accelerated the rate the
> > vulnerabilities are coming in. The effort that is being put into this
> > thing is vastly disproportional to the few programs that actually use
> > it, and those programs would be better served by userspace code anyway.
> >
> > These issues have been noted in many mailing list discussions already.
> > But until now they haven't been reflected in the documentation or
> > kconfig menu itself, and the vulnerabilities are still coming in.
> >
> > Let's go ahead and document the deprecation.
> >
> > This isn't intended to change anything overnight. After all, most Linux
> > distros won't be able to disable the kconfig options quite yet, mainly
> > because of iwd. But this should create a bit more impetus for these
> > userspace programs to be fixed, and the documentation update should also
> > help prevent more users from appearing.
> >
> > Signed-off-by: Eric Biggers <ebiggers@kernel.org>
> > ---
>
> Quick passing observation
> I noticed that when attempting to completely disable these Crypto APIs,
> I was experiencing boot failures with fips=1 enabled systems.
>
> Using 6.18-based kernel with an el9-based user space, I see the
> following hang in the early boot console from dracut-pre-pivot:
> Check integrity of kernel
> libkcapi - Error: AF_ALG: socket syscall failed (errno: -97)
> Allocation of hmac(sha512) cipher failed (-97)
>
> I haven't looked at every elX version, but at least in el9 and el10,
> they use libkcapi-hmaccalc to provide sha512hmac, which dracut [1]
> uses to calculate the HMAC value in do_fips().
>
> Digging further, I was only able to disable RNG and AEAD APIs, but
> not HASH and SKCIPHER APIs when FIPS was in the picture with el9++.
>
> I’m not sure how other distros do the same, but this could be problematic
> elsehwere if other distros went down the libkcapi route.
>
> [1] https://github.com/dracutdevs/dracut/blob/059/modules.d/01fips/fips.sh#L167
That seems to be an implementation of FIPS 140-3's integrity self-check.
A few observations:
- It could easily use userspace SHA-512 code instead. If including
libcrypto.so in the "FIPS cryptographic boundary" would cause
certification difficulties, then a sha512.c file could simply be added
to 'libkcapi-hmaccalc' which is already in it.
- It's compatible with all of the proposed hardening. It doesn't
require zero-copy performance. It runs as root, so it would be
compatible with a capability check. "hmac(sha512)" will need to be on
the algorithm allowlist anyway for iwd.
- FIPS 140-3 might also allow it to be simplified to use a plain hash
instead of pointlessly using HMAC with a fixed key.
Anyway, just another one of the long tail of odd users that could have
solved their problem in a better way. This one is at least compatible
with the hardening that's being considered.
By the way, also on the topic of FIPS 140-3, some people do use AF_ALG
for ACVP (even though it's not all that great for that purpose, either).
But ACVP is a testing thing, not something that is needed on production
systems. ACVP can just be run as root on a testing build; there's no
need to enable support for it in the actual production build.
- Eric
^ permalink raw reply
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Jeff Barnes @ 2026-05-04 17:41 UTC (permalink / raw)
To: Jon Kohler
Cc: Eric Biggers, linux-crypto@vger.kernel.org, Herbert Xu,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <4D424F50-7E9F-4B1F-AE9C-86D8526284E6@nutanix.com>
On May 4 2026, at 10:39 am, Jon Kohler <jon@nutanix.com> wrote:
>
> Quick passing observation
> I noticed that when attempting to completely disable these Crypto APIs,
> I was experiencing boot failures with fips=1 enabled systems.
>
> Using 6.18-based kernel with an el9-based user space, I see the
> following hang in the early boot console from dracut-pre-pivot:
> Check integrity of kernel
> libkcapi - Error: AF_ALG: socket syscall failed (errno: -97)
> Allocation of hmac(sha512) cipher failed (-97)
One thing that for certain that would cause this panic is the sha512hmac
binary that does the fips integrity check. On many distros this check is
called, for example by dracut among others, during initramfs to check
the integrity of the kernel before any crypto is used. On failure, the
kernel won't finish boot.
sha512hmac is a binary shipped with kcapitools. It uses libkcapi.
sha512hmac -> libkcapi -> AF_ALG.
Is there a planned replacement for this integrity check? I don't know of
anybody doing this for FIPS yet, but is there a case where IMA / EVM
could be a workaround?
Regards,
Jeff
>
> I haven't looked at every elX version, but at least in el9 and el10,
> they use libkcapi-hmaccalc to provide sha512hmac, which dracut [1]
> uses to calculate the HMAC value in do_fips().
>
> Digging further, I was only able to disable RNG and AEAD APIs, but
> not HASH and SKCIPHER APIs when FIPS was in the picture with el9++.
>
> I’m not sure how other distros do the same, but this could be problematic
> elsehwere if other distros went down the libkcapi route.
>
> [1] https://github.com/dracutdevs/dracut/blob/059/modules.d/01fips/fips.sh#L167
>
>
^ permalink raw reply
* Re: [RFC PATCH 1/2] net: af_unix: Useful handling of LSM denials on SCM_RIGHTS
From: Jori Koolstra @ 2026-05-04 17:43 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: Alexander Viro, Christian Brauner, Jan Kara, Eric Dumazet,
Paolo Abeni, Willem de Bruijn, David S . Miller, Jakub Kicinski,
Jens Axboe, Kees Cook, Simon Horman, Andy Lutomirski, Will Drewry,
Jeff Layton, Oleg Nesterov, Andrei Vagin, Pavel Tikhomirov,
Mateusz Guzik, Joel Granados, Charlie Mirabile, Aleksa Sarai,
linux-fsdevel, linux-kernel, netdev, io-uring
In-Reply-To: <CAAVpQUDKgWdgPjPmJKhNxofssasS8-RdaLAcbFXHMWH8ztMJXA@mail.gmail.com>
> Op 02-05-2026 03:24 CEST schreef Kuniyuki Iwashima <kuniyu@google.com>:
>
> > >
> > > Does this flag need per-recvmsg() granularity ?
> > >
> >
> > Perhaps not. What would be the alternative? A fcntl option for the socket fd?
>
> I'd add a new socket option like
>
> setsockopt(SOL_SOCKET, SO_RIGHTS_TRUNC, &(int){0}, sizeof(int));
>
>
I think this is reasonable suggestion (and better than using the MSG_ flags).
Let's just let this sit for a few days to see if anyone else has suggestions/
objections.
^ permalink raw reply
* [PATCH net] net: wan: fsl_ucc_hdlc: return NETDEV_TX_OK if skb was freed
From: Holger Brunck @ 2026-05-04 17:44 UTC (permalink / raw)
To: netdev
Cc: linuxppc-dev, andrew+netdev, chleroy, qiang.zhao, horms,
Holger Brunck
If the skb was freed in the ucc_hdlc_tx function and the packet marked
as dropped we need to return NETDEV_TX_OK. Otherwise the above layer
will try to requeue an already freed skb.
Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC")
Signed-off-by: Holger Brunck <holger.brunck@hitachienergy.com>
---
drivers/net/wan/fsl_ucc_hdlc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 7af558780bdc..6ce539151618 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -360,7 +360,7 @@ static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_dropped++;
dev_kfree_skb(skb);
netdev_err(dev, "No enough space for hdlc head\n");
- return -ENOMEM;
+ return NETDEV_TX_OK;
}
skb_push(skb, HDLC_HEAD_LEN);
@@ -377,7 +377,7 @@ static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_dropped++;
dev_kfree_skb(skb);
netdev_err(dev, "Wrong ppp header\n");
- return -ENOMEM;
+ return NETDEV_TX_OK;
}
dev->stats.tx_bytes += skb->len;
@@ -390,7 +390,7 @@ static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev)
default:
dev->stats.tx_dropped++;
dev_kfree_skb(skb);
- return -ENOMEM;
+ return NETDEV_TX_OK;
}
netdev_sent_queue(dev, skb->len);
spin_lock_irqsave(&priv->lock, flags);
--
2.47.3
^ permalink raw reply related
* Re: [PATCH] selftests: mptcp: add test for IPv6 subflow SLAB placement
From: Matthieu Baerts @ 2026-05-04 17:44 UTC (permalink / raw)
To: Vastargazing; +Cc: martineau, mptcp, netdev, linux-kselftest, shuah, stable, fw
In-Reply-To: <20260501-reply-mptcp-v6-initcall@vebohr>
Hi Vastargazing,
On 01/05/2026 19:01, Vastargazing wrote:
(...)
> One question if you don't mind: if something similar came up again and
> a test *was* warranted, which existing script would be the natural
> home? mptcp_join.sh seemed closest since it exercises the accept path,
> but i'm not sure if checking /proc/slabinfo fits there or if there's a
> better mechanism for that kind of thing.
It depends on what needs to be covered:
- diag.sh: check various counters
- mptcp_connect.sh: single path
- mptcp_join.sh: multiple paths
- mptcp_sockopt.sh: socket options
- pm_netlink.sh: in-kernel path-manager
- simult_flows.sh: small multiple paths perf tests
- userspace_pm.sh : userspace path-manager
- + kunit: token and crypto
- + packetdrill: various tests
So not mptcp_join.sh. Maybe diag.sh, or in packetdrill.
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply
* Re: [PATCH net v2] xfrm: esp: avoid in-place decrypt on shared skb frags
From: Hyunwoo Kim @ 2026-05-04 18:01 UTC (permalink / raw)
To: HexRabbit
Cc: netdev, Steffen Klassert, Greg Kroah-Hartman, Herbert Xu,
Simon Horman, David S . Miller, David Ahern, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Ido Schimmel, linux-kernel, stable,
imv4bel
In-Reply-To: <20260504152712.76305-1-h3xrabbit@gmail.com>
On Mon, May 04, 2026 at 11:27:12PM +0800, HexRabbit wrote:
> From: Kuan-Ting Chen <h3xrabbit@gmail.com>
>
> MSG_SPLICE_PAGES can attach pages from a pipe directly to an skb. TCP
> marks such skbs with SKBFL_SHARED_FRAG after skb_splice_from_iter(),
> so later paths that may modify packet data can first make a private
> copy. The IPv4/IPv6 datagram append paths did not set this flag when
> splicing pages into UDP skbs.
>
> That leaves an ESP-in-UDP packet made from shared pipe pages looking
> like an ordinary uncloned nonlinear skb. ESP input then takes the no-COW
> fast path for uncloned skbs without a frag_list and decrypts in place
> over data that is not owned privately by the skb.
>
> Mark IPv4/IPv6 datagram splice frags with SKBFL_SHARED_FRAG, matching
> TCP. Also make ESP input fall back to skb_cow_data() when the flag is
> present, so ESP does not decrypt externally backed frags in place.
> Private nonlinear skb frags still use the existing fast path.
>
> This intentionally does not change ESP output. In esp_output_head(),
> the path that appends the ESP trailer to existing skb tailroom without
> calling skb_cow_data() is not reachable for nonlinear skbs:
> skb_tailroom() returns zero when skb->data_len is nonzero, while ESP
> tailen is positive. Thus ESP output will either use the separate
> destination-frag path or fall back to skb_cow_data().
>
> Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
> Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
> Fixes: 7da0dde68486 ("ip, udp: Support MSG_SPLICE_PAGES")
> Fixes: 6d8192bd69bb ("ip6, udp6: Support MSG_SPLICE_PAGES")
> Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
> Reported-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
I dynamically tested this patch and confirm it resolves the
issue. Clean work.
One correction request before merge -- please drop the
second Reported-by tag (your own) from the trailer.
The report and patch for this issue were already posted on
the public netdev ML 6 days ago, i.e., the bug was already
publicly reported:
https://lore.kernel.org/all/afLDKSvAvMwGh7Fy@v4bel/
Credit for patch authorship is adequately covered by
Signed-off-by alone. Setting aside that your work proceeded
independently rather than as a review of my earlier
submission, the trailer should conform to convention to
avoid future misunderstanding.
No objections to the patch itself.
Best regards,
Hyunwoo Kim
^ permalink raw reply
* [PATCH net V5 0/4] net/mlx5: Fixes for Socket-Direct
From: Tariq Toukan @ 2026-05-04 18:02 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Shay Drory, Simon Horman, Patrisious Haddad, Parav Pandit,
Kees Cook, Gal Pressman, netdev, linux-rdma, linux-kernel,
Dragos Tatulea
Hi,
This series fixes several race conditions and bugs in the mlx5
Socket-Direct (SD) single netdev flow.
Patch 1 serializes mlx5_sd_init()/mlx5_sd_cleanup() with
mlx5_devcom_comp_lock() and tracks the SD group state on the primary
device, preventing concurrent or duplicate bring-up/tear-down.
Patch 2 fixes the debugfs "multi-pf" directory being stored on the
calling device's sd struct instead of the primary's, which caused
memory leaks and recreation errors when cleanup ran from a different PF.
Patch 3 fixes a race where a secondary PF could access the primary's
auxiliary device after it had been unbound, by holding the primary's
device lock while operating on its auxiliary device.
Patch 4 fixes missing cleanup on ETH probe errors. The analogous gap on
the resume path requires introducing sd_suspend/resume APIs that only
destroy FW resources and is left for a follow-up series.
Regards,
Tariq
---
V5:
- Adjust "net/mlx5: SD: Serialize init/cleanup" to clear each peer's
primary_dev pointer and the primary's secondaries[] under the comp
lock, and to set devcom not-ready in the !primary and state != UP
early-exit paths so the device cannot unregister while devcom is
still marked ready.
- Adjust "net/mlx5e: SD, Fix race condition in secondary device
probe/remove" to also take get_device()/put_device() on the primary's
adev, since device_lock() alone does not pin the kobject.
V4: https://lore.kernel.org/all/20260428060111.221086-1-tariqt@nvidia.com/
V3: https://lore.kernel.org/all/20260423123104.201552-1-tariqt@nvidia.com/
Shay Drory (4):
net/mlx5: SD: Serialize init/cleanup
net/mlx5: SD, Keep multi-pf debugfs entries on primary
net/mlx5e: SD, Fix missing cleanup on probe error
net/mlx5e: SD, Fix race condition in secondary device probe/remove
.../net/ethernet/mellanox/mlx5/core/en_main.c | 26 +++-
.../net/ethernet/mellanox/mlx5/core/lib/sd.c | 114 +++++++++++++++---
.../net/ethernet/mellanox/mlx5/core/lib/sd.h | 2 +
3 files changed, 122 insertions(+), 20 deletions(-)
base-commit: bd3a4795d5744f59a1f485379f1303e5e606f377
--
2.44.0
^ permalink raw reply
* [PATCH net V5 1/4] net/mlx5: SD: Serialize init/cleanup
From: Tariq Toukan @ 2026-05-04 18:02 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Shay Drory, Simon Horman, Patrisious Haddad, Parav Pandit,
Kees Cook, Gal Pressman, netdev, linux-rdma, linux-kernel,
Dragos Tatulea
In-Reply-To: <20260504180206.268568-1-tariqt@nvidia.com>
From: Shay Drory <shayd@nvidia.com>
mlx5_sd_init() / mlx5_sd_cleanup() may run from multiple PFs in the same
Socket-Direct group. This can cause the SD bring-up/tear-down sequence
to be executed more than once or interleaved across PFs.
Protect SD init/cleanup with mlx5_devcom_comp_lock() and track the SD
group state on the primary device. Skip init if the primary is already
UP, and skip cleanup unless the primary is UP.
The state check on cleanup is needed because sd_register() drops the
devcom comp lock between marking the comp ready and assigning
primary_dev on each peer. A concurrent cleanup that acquires the lock
in this window would observe devcom_is_ready==true while primary_dev
is still NULL (causing mlx5_sd_get_primary() to return NULL) or while
the FW alias setup performed by mlx5_sd_init()'s body has not yet run
(causing sd_cmd_unset_primary() to dereference a NULL tx_ft). Gate the
cleanup body on primary_sd->state == MLX5_SD_STATE_UP, which is set
only at the very end of mlx5_sd_init() under the same comp lock - so
observing UP guarantees primary_dev, secondaries[], tx_ft, and dfs are
all populated. Also bail explicitly if mlx5_sd_get_primary() returns
NULL, in case state is checked on a peer whose primary_dev hasn't been
assigned yet.
In addition, move mlx5_devcom_comp_set_ready(false) from sd_unregister()
into the cleanup's locked section, including the !primary and
state != UP early-exit paths, so the device cannot unregister and free
its struct mlx5_sd while devcom is still marked ready. A concurrent
init acquiring the devcom lock will now observe devcom is no longer
ready and bail out immediately.
Fixes: 381978d28317 ("net/mlx5e: Create single netdev per SD group")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../net/ethernet/mellanox/mlx5/core/lib/sd.c | 56 +++++++++++++++++--
1 file changed, 50 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index 762c783156b4..ec42685bdece 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -18,6 +18,7 @@ struct mlx5_sd {
u8 host_buses;
struct mlx5_devcom_comp_dev *devcom;
struct dentry *dfs;
+ u8 state;
bool primary;
union {
struct { /* primary */
@@ -31,6 +32,11 @@ struct mlx5_sd {
};
};
+enum mlx5_sd_state {
+ MLX5_SD_STATE_DOWN = 0,
+ MLX5_SD_STATE_UP,
+};
+
static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
{
struct mlx5_sd *sd = mlx5_get_sd(dev);
@@ -270,9 +276,6 @@ static void sd_unregister(struct mlx5_core_dev *dev)
{
struct mlx5_sd *sd = mlx5_get_sd(dev);
- mlx5_devcom_comp_lock(sd->devcom);
- mlx5_devcom_comp_set_ready(sd->devcom, false);
- mlx5_devcom_comp_unlock(sd->devcom);
mlx5_devcom_unregister_component(sd->devcom);
}
@@ -426,6 +429,7 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
struct mlx5_core_dev *primary, *pos, *to;
struct mlx5_sd *sd = mlx5_get_sd(dev);
u8 alias_key[ACCESS_KEY_LEN];
+ struct mlx5_sd *primary_sd;
int err, i;
err = sd_init(dev);
@@ -440,10 +444,17 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
if (err)
goto err_sd_cleanup;
+ mlx5_devcom_comp_lock(sd->devcom);
if (!mlx5_devcom_comp_is_ready(sd->devcom))
- return 0;
+ goto out;
primary = mlx5_sd_get_primary(dev);
+ if (!primary)
+ goto out;
+
+ primary_sd = mlx5_get_sd(primary);
+ if (primary_sd->state != MLX5_SD_STATE_DOWN)
+ goto out;
for (i = 0; i < ACCESS_KEY_LEN; i++)
alias_key[i] = get_random_u8();
@@ -472,6 +483,9 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
sd->group_id, mlx5_devcom_comp_get_size(sd->devcom));
sd_print_group(primary);
+ primary_sd->state = MLX5_SD_STATE_UP;
+out:
+ mlx5_devcom_comp_unlock(sd->devcom);
return 0;
err_unset_secondaries:
@@ -481,6 +495,15 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
sd_cmd_unset_primary(primary);
debugfs_remove_recursive(sd->dfs);
err_sd_unregister:
+ mlx5_sd_for_each_secondary(i, primary, pos) {
+ struct mlx5_sd *peer_sd = mlx5_get_sd(pos);
+
+ primary_sd->secondaries[i - 1] = NULL;
+ peer_sd->primary_dev = NULL;
+ }
+ primary_sd->primary = false;
+ mlx5_devcom_comp_set_ready(sd->devcom, false);
+ mlx5_devcom_comp_unlock(sd->devcom);
sd_unregister(dev);
err_sd_cleanup:
sd_cleanup(dev);
@@ -491,22 +514,43 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
{
struct mlx5_sd *sd = mlx5_get_sd(dev);
struct mlx5_core_dev *primary, *pos;
+ struct mlx5_sd *primary_sd;
int i;
if (!sd)
return;
+ mlx5_devcom_comp_lock(sd->devcom);
if (!mlx5_devcom_comp_is_ready(sd->devcom))
- goto out;
+ goto out_unlock;
primary = mlx5_sd_get_primary(dev);
+ if (!primary)
+ goto out_ready_false;
+
+ primary_sd = mlx5_get_sd(primary);
+ if (primary_sd->state != MLX5_SD_STATE_UP)
+ goto out_clear_peers;
+
mlx5_sd_for_each_secondary(i, primary, pos)
sd_cmd_unset_secondary(pos);
sd_cmd_unset_primary(primary);
debugfs_remove_recursive(sd->dfs);
sd_info(primary, "group id %#x, uncombined\n", sd->group_id);
-out:
+ primary_sd->state = MLX5_SD_STATE_DOWN;
+out_clear_peers:
+ mlx5_sd_for_each_secondary(i, primary, pos) {
+ struct mlx5_sd *peer_sd = mlx5_get_sd(pos);
+
+ primary_sd->secondaries[i - 1] = NULL;
+ peer_sd->primary_dev = NULL;
+ }
+ primary_sd->primary = false;
+out_ready_false:
+ mlx5_devcom_comp_set_ready(sd->devcom, false);
+out_unlock:
+ mlx5_devcom_comp_unlock(sd->devcom);
sd_unregister(dev);
sd_cleanup(dev);
}
--
2.44.0
^ permalink raw reply related
* [PATCH net V5 3/4] net/mlx5e: SD, Fix missing cleanup on probe error
From: Tariq Toukan @ 2026-05-04 18:02 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Shay Drory, Simon Horman, Patrisious Haddad, Parav Pandit,
Kees Cook, Gal Pressman, netdev, linux-rdma, linux-kernel,
Dragos Tatulea
In-Reply-To: <20260504180206.268568-1-tariqt@nvidia.com>
From: Shay Drory <shayd@nvidia.com>
When _mlx5e_probe() fails, the preceding successful mlx5_sd_init() is
not undone. Auxiliary bus probe failure skips binding, so mlx5e_remove()
is never called for that adev and the matching mlx5_sd_cleanup() never
runs - leaking the per-dev SD struct.
Call mlx5_sd_cleanup() on the probe error path to balance
mlx5_sd_init().
A similar gap exists on the resume path: mlx5_sd_init() and
mlx5_sd_cleanup() are currently bundled with both probe/remove and
suspend/resume, even though only the FW alias state actually needs to
follow the suspend/resume lifecycle - the sd struct allocation and
devcom membership are software state that should track the full bound
lifetime. As a result, a failed resume can leave a still-bound device
with sd == NULL, which mlx5_sd_get_adev() can't distinguish from a
non-SD device. Fixing this requires sd_suspend/resume APIs which will
only destroy FW resources and is left for a follow-up series.
Fixes: 381978d28317 ("net/mlx5e: Create single netdev per SD group")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5a46870c4b74..e21affd0ffc4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6775,8 +6775,8 @@ static int mlx5e_resume(struct auxiliary_device *adev)
actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx);
if (actual_adev)
- return _mlx5e_resume(actual_adev);
- return 0;
+ err = _mlx5e_resume(actual_adev);
+ return err;
}
static int _mlx5e_suspend(struct auxiliary_device *adev, bool pre_netdev_reg)
@@ -6912,9 +6912,16 @@ static int mlx5e_probe(struct auxiliary_device *adev,
return err;
actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx);
- if (actual_adev)
- return _mlx5e_probe(actual_adev);
+ if (actual_adev) {
+ err = _mlx5e_probe(actual_adev);
+ if (err)
+ goto sd_cleanup;
+ }
return 0;
+
+sd_cleanup:
+ mlx5_sd_cleanup(mdev);
+ return err;
}
static void _mlx5e_remove(struct auxiliary_device *adev)
--
2.44.0
^ permalink raw reply related
* [PATCH net V5 4/4] net/mlx5e: SD, Fix race condition in secondary device probe/remove
From: Tariq Toukan @ 2026-05-04 18:02 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Shay Drory, Simon Horman, Patrisious Haddad, Parav Pandit,
Kees Cook, Gal Pressman, netdev, linux-rdma, linux-kernel,
Dragos Tatulea
In-Reply-To: <20260504180206.268568-1-tariqt@nvidia.com>
From: Shay Drory <shayd@nvidia.com>
When utilizing Socket-Direct single netdev functionality the driver
resolves the actual auxiliary device using mlx5_sd_get_adev(). However,
the current implementation returns the primary ETH auxiliary device
without holding the device lock, leading to a potential race condition
where the ETH device could be unbound or removed concurrently during
probe, suspend, resume, or remove operations.[1]
Fix this by introducing mlx5_sd_put_adev() and updating
mlx5_sd_get_adev() so that secondaries devices would get a ref and
acquire the device lock of the returned auxiliary device. After the lock
is acquired, a second devcom check is needed[2].
In addition, update The callers to pair the get operation with the new
put operation, ensuring the lock is held while the auxiliary device is
being operated on and released afterwards.
The "primary" designation is determined once in sd_register(). It's set
before devcom is marked ready, and it never changes after that.
In Addition, The primary path never locks a secondary: When the primary
device invoke mlx5_sd_get_adev(), it sees dev == primary and returns.
no additional lock is taken.
Therefore lock ordering is always: secondary_lock -> primary_lock. The
reverse never happens, so ABBA deadlock is impossible.
[1]
for example:
BUG: kernel NULL pointer dereference, address: 0000000000000370
PGD 0 P4D 0
Oops: Oops: 0000 [#1] SMP
CPU: 4 UID: 0 PID: 3945 Comm: bash Not tainted 6.19.0-rc3+ #1 NONE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
RIP: 0010:mlx5e_dcbnl_dscp_app+0x23/0x100 [mlx5_core]
Call Trace:
<TASK>
mlx5e_remove+0x82/0x12a [mlx5_core]
device_release_driver_internal+0x194/0x1f0
bus_remove_device+0xc6/0x140
device_del+0x159/0x3c0
? devl_param_driverinit_value_get+0x29/0x80
mlx5_rescan_drivers_locked+0x92/0x160 [mlx5_core]
mlx5_unregister_device+0x34/0x50 [mlx5_core]
mlx5_uninit_one+0x43/0xb0 [mlx5_core]
remove_one+0x4e/0xc0 [mlx5_core]
pci_device_remove+0x39/0xa0
device_release_driver_internal+0x194/0x1f0
unbind_store+0x99/0xa0
kernfs_fop_write_iter+0x12e/0x1e0
vfs_write+0x215/0x3d0
ksys_write+0x5f/0xd0
do_syscall_64+0x55/0xe90
entry_SYSCALL_64_after_hwframe+0x4b/0x53
[2]
CPU0 (primary) CPU1 (secondary)
==========================================================================
mlx5e_remove() (device_lock held)
mlx5e_remove() (2nd device_lock held)
mlx5_sd_get_adev()
mlx5_devcom_comp_is_ready() => true
device_lock(primary)
mlx5_sd_get_adev() ==> ret adev
_mlx5e_remove()
mlx5_sd_cleanup()
// mlx5e_remove finished
// releasing device_lock
//need another check here...
mlx5_devcom_comp_is_ready() => false
Fixes: 381978d28317 ("net/mlx5e: Create single netdev per SD group")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../net/ethernet/mellanox/mlx5/core/en_main.c | 11 +++++-
.../net/ethernet/mellanox/mlx5/core/lib/sd.c | 39 +++++++++++++++++--
.../net/ethernet/mellanox/mlx5/core/lib/sd.h | 2 +
3 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index e21affd0ffc4..b09806dfebe5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6774,8 +6774,10 @@ static int mlx5e_resume(struct auxiliary_device *adev)
return err;
actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx);
- if (actual_adev)
+ if (actual_adev) {
err = _mlx5e_resume(actual_adev);
+ mlx5_sd_put_adev(actual_adev, adev);
+ }
return err;
}
@@ -6815,6 +6817,8 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
err = _mlx5e_suspend(actual_adev, false);
mlx5_sd_cleanup(mdev);
+ if (actual_adev)
+ mlx5_sd_put_adev(actual_adev, adev);
return err;
}
@@ -6916,11 +6920,14 @@ static int mlx5e_probe(struct auxiliary_device *adev,
err = _mlx5e_probe(actual_adev);
if (err)
goto sd_cleanup;
+ mlx5_sd_put_adev(actual_adev, adev);
}
return 0;
sd_cleanup:
mlx5_sd_cleanup(mdev);
+ if (actual_adev)
+ mlx5_sd_put_adev(actual_adev, adev);
return err;
}
@@ -6973,6 +6980,8 @@ static void mlx5e_remove(struct auxiliary_device *adev)
_mlx5e_remove(actual_adev);
mlx5_sd_cleanup(mdev);
+ if (actual_adev)
+ mlx5_sd_put_adev(actual_adev, adev);
}
static const struct auxiliary_device_id mlx5e_id_table[] = {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index 89b7e4d67303..6e199161b008 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -562,22 +562,55 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
sd_cleanup(dev);
}
+/* Lock order:
+ * primary: actual_adev_lock -> SD devcom comp lock
+ * secondary: SD devcom comp lock -> (drop) -> actual_adev_lock
+ * The two locks are never held together, so no ABBA.
+ */
struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
struct auxiliary_device *adev,
int idx)
{
struct mlx5_sd *sd = mlx5_get_sd(dev);
struct mlx5_core_dev *primary;
+ struct mlx5_adev *primary_adev;
if (!sd)
return adev;
- if (!mlx5_devcom_comp_is_ready(sd->devcom))
+ mlx5_devcom_comp_lock(sd->devcom);
+ if (!mlx5_devcom_comp_is_ready(sd->devcom)) {
+ mlx5_devcom_comp_unlock(sd->devcom);
return NULL;
+ }
primary = mlx5_sd_get_primary(dev);
- if (dev == primary)
+ if (!primary || dev == primary) {
+ mlx5_devcom_comp_unlock(sd->devcom);
return adev;
+ }
+
+ primary_adev = primary->priv.adev[idx];
+ get_device(&primary_adev->adev.dev);
+ mlx5_devcom_comp_unlock(sd->devcom);
- return &primary->priv.adev[idx]->adev;
+ device_lock(&primary_adev->adev.dev);
+ /* Primary may have completed remove between dropping devcom and
+ * acquiring device_lock; recheck.
+ */
+ if (!mlx5_devcom_comp_is_ready(sd->devcom)) {
+ device_unlock(&primary_adev->adev.dev);
+ put_device(&primary_adev->adev.dev);
+ return NULL;
+ }
+ return &primary_adev->adev;
+}
+
+void mlx5_sd_put_adev(struct auxiliary_device *actual_adev,
+ struct auxiliary_device *adev)
+{
+ if (actual_adev != adev) {
+ device_unlock(&actual_adev->dev);
+ put_device(&actual_adev->dev);
+ }
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
index 137efaf9aabc..9bfd5b9756b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h
@@ -15,6 +15,8 @@ struct mlx5_core_dev *mlx5_sd_ch_ix_get_dev(struct mlx5_core_dev *primary, int c
struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
struct auxiliary_device *adev,
int idx);
+void mlx5_sd_put_adev(struct auxiliary_device *actual_adev,
+ struct auxiliary_device *adev);
int mlx5_sd_init(struct mlx5_core_dev *dev);
void mlx5_sd_cleanup(struct mlx5_core_dev *dev);
--
2.44.0
^ permalink raw reply related
* [PATCH net V5 2/4] net/mlx5: SD, Keep multi-pf debugfs entries on primary
From: Tariq Toukan @ 2026-05-04 18:02 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Saeed Mahameed, Tariq Toukan, Mark Bloch, Leon Romanovsky,
Shay Drory, Simon Horman, Patrisious Haddad, Parav Pandit,
Kees Cook, Gal Pressman, netdev, linux-rdma, linux-kernel,
Dragos Tatulea
In-Reply-To: <20260504180206.268568-1-tariqt@nvidia.com>
From: Shay Drory <shayd@nvidia.com>
mlx5_sd_init() creates the "multi-pf" debugfs directory under the
primary device debugfs root, but stored the dentry in the calling
device's sd struct. When sd_cleanup() run on a different PF,
this leads to using the wrong sd->dfs for removing entries, which
results in memory leak and an error in when re-creating the SD.[1]
Fix it by explicitly storing the debugfs dentry in the primary
device sd struct and use it for all per-group files.
[1]
debugfs: 'multi-pf' already exists in '0000:08:00.1'
Fixes: 4375130bf527 ("net/mlx5: SD, Add debugfs")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../net/ethernet/mellanox/mlx5/core/lib/sd.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
index ec42685bdece..89b7e4d67303 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
@@ -463,9 +463,13 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
if (err)
goto err_sd_unregister;
- sd->dfs = debugfs_create_dir("multi-pf", mlx5_debugfs_get_dev_root(primary));
- debugfs_create_x32("group_id", 0400, sd->dfs, &sd->group_id);
- debugfs_create_file("primary", 0400, sd->dfs, primary, &dev_fops);
+ primary_sd->dfs =
+ debugfs_create_dir("multi-pf",
+ mlx5_debugfs_get_dev_root(primary));
+ debugfs_create_x32("group_id", 0400, primary_sd->dfs,
+ &primary_sd->group_id);
+ debugfs_create_file("primary", 0400, primary_sd->dfs, primary,
+ &dev_fops);
mlx5_sd_for_each_secondary(i, primary, pos) {
char name[32];
@@ -475,7 +479,8 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
goto err_unset_secondaries;
snprintf(name, sizeof(name), "secondary_%d", i - 1);
- debugfs_create_file(name, 0400, sd->dfs, pos, &dev_fops);
+ debugfs_create_file(name, 0400, primary_sd->dfs, pos,
+ &dev_fops);
}
@@ -493,7 +498,8 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
mlx5_sd_for_each_secondary_to(i, primary, to, pos)
sd_cmd_unset_secondary(pos);
sd_cmd_unset_primary(primary);
- debugfs_remove_recursive(sd->dfs);
+ debugfs_remove_recursive(primary_sd->dfs);
+ primary_sd->dfs = NULL;
err_sd_unregister:
mlx5_sd_for_each_secondary(i, primary, pos) {
struct mlx5_sd *peer_sd = mlx5_get_sd(pos);
@@ -535,7 +541,8 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
mlx5_sd_for_each_secondary(i, primary, pos)
sd_cmd_unset_secondary(pos);
sd_cmd_unset_primary(primary);
- debugfs_remove_recursive(sd->dfs);
+ debugfs_remove_recursive(primary_sd->dfs);
+ primary_sd->dfs = NULL;
sd_info(primary, "group id %#x, uncombined\n", sd->group_id);
primary_sd->state = MLX5_SD_STATE_DOWN;
--
2.44.0
^ permalink raw reply related
* Re: [PATCH net 4/4] mptcp: sockopt: increase seq in mptcp_setsockopt_all_sf
From: Matthieu Baerts @ 2026-05-04 18:08 UTC (permalink / raw)
To: netdev
Cc: mptcp, linux-kernel, stable, Mat Martineau, Geliang Tang,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Florian Westphal, Gang Yan, Dmytro Shytyi
In-Reply-To: <20260501-net-mptcp-misc-fixes-7-1-rc3-v1-4-b70118df778e@kernel.org>
Hello,
On 01/05/2026 21:35, Matthieu Baerts (NGI0) wrote:
> mptcp_setsockopt_all_sf() was missing a call to sockopt_seq_inc(). This
> is required not to cause missing synchronization for newer subflows
> created later on.
>
> This helper is called each time a socket option is set on subflows, and
> future ones will need to inherit this option after their creation.
Regarding Sashiko's review, I think this can be ignored: the comments
are about existing code / architecture. In short, for the moment, most
places in sockopt.c assumes that if there is an error to set a socket
option with one subflow, the error will be visible when setting this
option on all of them. Maybe (not sure) this could be changed, but then
this can be done later, when modifying all the other places. Here I
think it is better to keep the same logic as what is done with the other
options.
https://sashiko.dev/#/patchset/20260501-net-mptcp-misc-fixes-7-1-rc3-v1-0-b70118df778e%40kernel.org
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply
* [PATCH net V3 0/3] net/mlx5e: PSP fixes
From: Tariq Toukan @ 2026-05-04 18:10 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch, Daniel Zahka, Willem de Bruijn, Cosmin Ratiu,
Raed Salem, Rahul Rameshbabu, Dragos Tatulea, Kees Cook, netdev,
linux-rdma, linux-kernel, Gal Pressman
Hi,
This patchset provides bug fixes from Cosmin to the mlx5e PSP feature.
Thanks,
Tariq.
---
V3:
- Moved mlx5e_psp_init() changes into separate patch, with proper
motivation and "Fixes" tag.
V2: https://lore.kernel.org/all/20260426083819.208937-1-tariqt@nvidia.com/
V1: https://lore.kernel.org/all/20260417050201.192070-1-tariqt@nvidia.com/
Cosmin Ratiu (3):
net/mlx5e: psp: Fix invalid access on PSP dev registration fail
net/mlx5e: psp: Expose only a fully initialized priv->psp
net/mlx5e: psp: Hook PSP dev reg/unreg to profile enable/disable
.../mellanox/mlx5/core/en_accel/psp.c | 36 ++++++++++---------
.../net/ethernet/mellanox/mlx5/core/en_main.c | 4 +--
2 files changed, 22 insertions(+), 18 deletions(-)
base-commit: bd3a4795d5744f59a1f485379f1303e5e606f377
--
2.44.0
^ permalink raw reply
* [PATCH net V3 2/3] net/mlx5e: psp: Expose only a fully initialized priv->psp
From: Tariq Toukan @ 2026-05-04 18:10 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch, Daniel Zahka, Willem de Bruijn, Cosmin Ratiu,
Raed Salem, Rahul Rameshbabu, Dragos Tatulea, Kees Cook, netdev,
linux-rdma, linux-kernel, Gal Pressman
In-Reply-To: <20260504181100.269334-1-tariqt@nvidia.com>
From: Cosmin Ratiu <cratiu@nvidia.com>
Currently, during PSP init, priv->psp is initialized to an incompletely
built psp struct. Additionally, on fs init failure priv->psp is reset to
NULL.
Change this so that only a fully initialized priv->psp is set, which
makes the code easier to reason about in failure scenarios.
Fixes: af2196f49480 ("net/mlx5e: Implement PSP operations .assoc_add and .assoc_del")
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
index 1ff818fb48df..d9adb993e64d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
@@ -1139,22 +1139,18 @@ int mlx5e_psp_init(struct mlx5e_priv *priv)
if (!psp)
return -ENOMEM;
- priv->psp = psp;
fs = mlx5e_accel_psp_fs_init(priv);
if (IS_ERR(fs)) {
err = PTR_ERR(fs);
- goto out_err;
+ kfree(psp);
+ return err;
}
psp->fs = fs;
+ priv->psp = psp;
mlx5_core_dbg(priv->mdev, "PSP attached to netdevice\n");
return 0;
-
-out_err:
- priv->psp = NULL;
- kfree(psp);
- return err;
}
void mlx5e_psp_cleanup(struct mlx5e_priv *priv)
--
2.44.0
^ permalink raw reply related
* [PATCH net V3 1/3] net/mlx5e: psp: Fix invalid access on PSP dev registration fail
From: Tariq Toukan @ 2026-05-04 18:10 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch, Daniel Zahka, Willem de Bruijn, Cosmin Ratiu,
Raed Salem, Rahul Rameshbabu, Dragos Tatulea, Kees Cook, netdev,
linux-rdma, linux-kernel, Gal Pressman
In-Reply-To: <20260504181100.269334-1-tariqt@nvidia.com>
From: Cosmin Ratiu <cratiu@nvidia.com>
priv->psp->psp is initialized with the PSP device as returned by
psp_dev_create(). This could also return an error, in which case a
future psp_dev_unregister() will result in unpleasantness.
Avoid that by using a local variable and only saving the PSP device when
registration succeeds.
In case psp_dev_create() fails, priv->psp and steering structs are left
in place, but they will be inert. The unchecked access of priv->psp in
mlx5e_psp_offload_handle_rx_skb() won't happen because without a PSP
device, there can be no SAs added and therefore no packets will be
successfully decrypted and be handed off to the SW handler.
Fixes: 89ee2d92f66c ("net/mlx5e: Support PSP offload functionality")
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../mellanox/mlx5/core/en_accel/psp.c | 26 ++++++++++++-------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
index 6a50b6dec0fa..1ff818fb48df 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
@@ -1070,29 +1070,37 @@ static struct psp_dev_ops mlx5_psp_ops = {
void mlx5e_psp_unregister(struct mlx5e_priv *priv)
{
- if (!priv->psp || !priv->psp->psp)
+ struct mlx5e_psp *psp = priv->psp;
+
+ if (!psp || !psp->psp)
return;
- psp_dev_unregister(priv->psp->psp);
+ psp_dev_unregister(psp->psp);
+ psp->psp = NULL;
}
void mlx5e_psp_register(struct mlx5e_priv *priv)
{
+ struct mlx5e_psp *psp = priv->psp;
+ struct psp_dev *psd;
+
/* FW Caps missing */
if (!priv->psp)
return;
- priv->psp->caps.assoc_drv_spc = sizeof(u32);
- priv->psp->caps.versions = 1 << PSP_VERSION_HDR0_AES_GCM_128;
+ psp->caps.assoc_drv_spc = sizeof(u32);
+ psp->caps.versions = 1 << PSP_VERSION_HDR0_AES_GCM_128;
if (MLX5_CAP_PSP(priv->mdev, psp_crypto_esp_aes_gcm_256_encrypt) &&
MLX5_CAP_PSP(priv->mdev, psp_crypto_esp_aes_gcm_256_decrypt))
- priv->psp->caps.versions |= 1 << PSP_VERSION_HDR0_AES_GCM_256;
+ psp->caps.versions |= 1 << PSP_VERSION_HDR0_AES_GCM_256;
- priv->psp->psp = psp_dev_create(priv->netdev, &mlx5_psp_ops,
- &priv->psp->caps, NULL);
- if (IS_ERR(priv->psp->psp))
+ psd = psp_dev_create(priv->netdev, &mlx5_psp_ops, &psp->caps, NULL);
+ if (IS_ERR(psd)) {
mlx5_core_err(priv->mdev, "PSP failed to register due to %pe\n",
- priv->psp->psp);
+ psd);
+ return;
+ }
+ psp->psp = psd;
}
int mlx5e_psp_init(struct mlx5e_priv *priv)
--
2.44.0
^ permalink raw reply related
* [PATCH net V3 3/3] net/mlx5e: psp: Hook PSP dev reg/unreg to profile enable/disable
From: Tariq Toukan @ 2026-05-04 18:11 UTC (permalink / raw)
To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
David S. Miller
Cc: Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch, Daniel Zahka, Willem de Bruijn, Cosmin Ratiu,
Raed Salem, Rahul Rameshbabu, Dragos Tatulea, Kees Cook, netdev,
linux-rdma, linux-kernel, Gal Pressman
In-Reply-To: <20260504181100.269334-1-tariqt@nvidia.com>
From: Cosmin Ratiu <cratiu@nvidia.com>
devlink reload while PSP connections are active does:
mlx5_unload_one_devl_locked() -> mlx5_detach_device()
-> _mlx5e_suspend()
-> mlx5e_detach_netdev()
-> profile->cleanup_rx
-> profile->cleanup_tx
-> mlx5e_destroy_mdev_resources() -> mlx5_core_dealloc_pd() fails:
...
mlx5_core 0000:08:00.0: mlx5_cmd_out_err:821:(pid 19722):
DEALLOC_PD(0x801) op_mod(0x0) failed, status bad resource state(0x9),
syndrome (0xef0c8a), err(-22)
...
The reason for failure is the existence of TX keys, which are removed by
the PSP dev unregistration happening in:
profile->cleanup() -> mlx5e_psp_unregister() -> mlx5e_psp_cleanup()
-> psp_dev_unregister()
...but this isn't invoked in the devlink reload flow, only when changing
the NIC profile (e.g. when transitioning to switchdev mode) or on dev
teardown.
Move PSP device registration into mlx5e_nic_enable(), and unregistration
into the corresponding mlx5e_nic_disable(). These functions are called
during netdev attach/detach after RX & TX are set up.
This ensures that the keys will be gone by the time the PD is destroyed.
Fixes: 89ee2d92f66c ("net/mlx5e: Support PSP offload functionality")
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5a46870c4b74..8e9443caa933 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6023,7 +6023,6 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
if (take_rtnl)
rtnl_lock();
- mlx5e_psp_register(priv);
/* update XDP supported features */
mlx5e_set_xdp_feature(priv);
@@ -6036,7 +6035,6 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
mlx5e_health_destroy_reporters(priv);
- mlx5e_psp_unregister(priv);
mlx5e_ktls_cleanup(priv);
mlx5e_psp_cleanup(priv);
mlx5e_fs_cleanup(priv->fs);
@@ -6160,6 +6158,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
mlx5e_fs_init_l2_addr(priv->fs, netdev);
mlx5e_ipsec_init(priv);
+ mlx5e_psp_register(priv);
err = mlx5e_macsec_init(priv);
if (err)
@@ -6230,6 +6229,7 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
mlx5_lag_remove_netdev(mdev, priv->netdev);
mlx5_vxlan_reset_to_default(mdev->vxlan);
mlx5e_macsec_cleanup(priv);
+ mlx5e_psp_unregister(priv);
mlx5e_ipsec_cleanup(priv);
}
--
2.44.0
^ permalink raw reply related
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Jeff Barnes @ 2026-05-04 18:12 UTC (permalink / raw)
To: Eric Biggers
Cc: Jon Kohler, linux-crypto@vger.kernel.org, Herbert Xu,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <20260504173952.GA2291@sol>
On May 4 2026, at 1:39 pm, Eric Biggers <ebiggers@kernel.org> wrote:
>
> That seems to be an implementation of FIPS 140-3's integrity self-check.
> A few observations:
>
> - It could easily use userspace SHA-512 code instead. If including
> libcrypto.so in the "FIPS cryptographic boundary" would cause
> certification difficulties, then a sha512.c file could simply be added
> to 'libkcapi-hmaccalc' which is already in it.
Indeed expanding the crypto boundary to include libcrypto.so would cause
certification difficulties, it would mean certifying all of libcrypto.so
with the kernel. There *may* be a case for saying that it is outside the
module boundary but only if:
* The integrity mechanism is clearly external
* The cryptographic module refuses to operate unless integrity is confirmed
* The trust relationship is clearly documented
I don't see how this could be justified cleanly without significant pushback.
>
> - It's compatible with all of the proposed hardening. It doesn't
> require zero-copy performance. It runs as root, so it would be
> compatible with a capability check. "hmac(sha512)" will need to be on
> the algorithm allowlist anyway for iwd.
>
> - FIPS 140-3 might also allow it to be simplified to use a plain hash
> instead of pointlessly using HMAC with a fixed key.
FIPS 140‑3 (via ISO/IEC 19790) draws a hard distinction between:
* Integrity checking (cryptographic protection)
* Integrity measurement (detection only)
A plain hash provides no protection against an attacker who can modify
both the object and its reference hash.
>
> By the way, also on the topic of FIPS 140-3, some people do use AF_ALG
> for ACVP (even though it's not all that great for that purpose, either).
> But ACVP is a testing thing, not something that is needed on production
> systems. ACVP can just be run as root on a testing build; there's no
> need to enable support for it in the actual production build.
Agreed it's not a good use case. Unless/until pkcs1 is supported, I
don't see how you can use it for all of the test cases. Plus as
evidenced by Ubuntu's new cert, it requires validating the library.
>
> - Eric
>
^ permalink raw reply
* [PATCH v1] gve: Use generic power management
From: Vaibhav Gupta @ 2026-05-04 18:21 UTC (permalink / raw)
To: Joshua Washington, Harshitha Ramamurthy, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Willem de Bruijn, Ankit Garg, Tim Hostetler, Alok Tiwari,
John Fraker, Matt Olson, Praveen Kaligineedi
Cc: Vaibhav Gupta, netdev, linux-kernel
Switch to the generic power management and remove the usage of legacy
(pci_driver) hooks.
Signed-off-by: Vaibhav Gupta <vaibhavgupta40@gmail.com>
---
drivers/net/ethernet/google/gve/gve_main.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 424d973c97f2..b7bac6bf89e2 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -2967,9 +2967,9 @@ static void gve_shutdown(struct pci_dev *pdev)
rtnl_unlock();
}
-#ifdef CONFIG_PM
-static int gve_suspend(struct pci_dev *pdev, pm_message_t state)
+static int gve_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct gve_priv *priv = netdev_priv(netdev);
bool was_up = netif_running(priv->dev);
@@ -2990,8 +2990,9 @@ static int gve_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int gve_resume(struct pci_dev *pdev)
+static int gve_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct gve_priv *priv = netdev_priv(netdev);
int err;
@@ -3004,7 +3005,8 @@ static int gve_resume(struct pci_dev *pdev)
rtnl_unlock();
return err;
}
-#endif /* CONFIG_PM */
+
+static DEFINE_SIMPLE_DEV_PM_OPS(gve_pm_ops, gve_suspend, gve_resume);
static const struct pci_device_id gve_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_GOOGLE, PCI_DEV_ID_GVNIC) },
@@ -3017,10 +3019,7 @@ static struct pci_driver gve_driver = {
.probe = gve_probe,
.remove = gve_remove,
.shutdown = gve_shutdown,
-#ifdef CONFIG_PM
- .suspend = gve_suspend,
- .resume = gve_resume,
-#endif
+ .driver.pm = &gve_pm_ops,
};
module_pci_driver(gve_driver);
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Eric Biggers @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jeff Barnes
Cc: Jon Kohler, linux-crypto@vger.kernel.org, Herbert Xu,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <F100C726-F841-461B-BE2F-C2018C122426@getmailspring.com>
On Mon, May 04, 2026 at 02:12:11PM -0400, Jeff Barnes wrote:
> A plain hash provides no protection against an attacker who can modify
> both the object and its reference hash.
Same with the HMAC, because in the FIPS integrity check the key isn't
secret. You can find the key used by the sha512hmac binary here:
https://github.com/smuellerDD/libkcapi/blob/master/apps/kcapi-hasher.c#L125
- Eric
^ permalink raw reply
* Re: [PATCH] crypto: af_alg - Document the deprecation of AF_ALG
From: Simo Sorce @ 2026-05-04 18:27 UTC (permalink / raw)
To: Jeff Barnes, Eric Biggers
Cc: Jon Kohler, linux-crypto@vger.kernel.org, Herbert Xu,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Linus Torvalds
In-Reply-To: <F100C726-F841-461B-BE2F-C2018C122426@getmailspring.com>
On Mon, 2026-05-04 at 14:12 -0400, Jeff Barnes wrote:
>
> On May 4 2026, at 1:39 pm, Eric Biggers <ebiggers@kernel.org> wrote:
> >
> > That seems to be an implementation of FIPS 140-3's integrity self-check.
> > A few observations:
> >
> > - It could easily use userspace SHA-512 code instead. If including
> > libcrypto.so in the "FIPS cryptographic boundary" would cause
> > certification difficulties, then a sha512.c file could simply be added
> > to 'libkcapi-hmaccalc' which is already in it.
>
> Indeed expanding the crypto boundary to include libcrypto.so would cause
> certification difficulties, it would mean certifying all of libcrypto.so
> with the kernel. There *may* be a case for saying that it is outside the
> module boundary but only if:
>
> * The integrity mechanism is clearly external
> * The cryptographic module refuses to operate unless integrity is confirmed
> * The trust relationship is clearly documented
>
> I don't see how this could be justified cleanly without significant pushback.
>
> >
> > - It's compatible with all of the proposed hardening. It doesn't
> > require zero-copy performance. It runs as root, so it would be
> > compatible with a capability check. "hmac(sha512)" will need to be on
> > the algorithm allowlist anyway for iwd.
> >
> > - FIPS 140-3 might also allow it to be simplified to use a plain hash
> > instead of pointlessly using HMAC with a fixed key.
>
> FIPS 140‑3 (via ISO/IEC 19790) draws a hard distinction between:
> * Integrity checking (cryptographic protection)
> * Integrity measurement (detection only)
>
> A plain hash provides no protection against an attacker who can modify
> both the object and its reference hash.
The integrity mechanism is not build to detect adversarial tampering
(at least at level 1), that is not its purpose.
That said a HMAC is just a hash with a secret key in the mix, it does
not change the conditions wrt Hash if the key is known.
> > By the way, also on the topic of FIPS 140-3, some people do use AF_ALG
> > for ACVP (even though it's not all that great for that purpose, either).
> > But ACVP is a testing thing, not something that is needed on production
> > systems. ACVP can just be run as root on a testing build; there's no
> > need to enable support for it in the actual production build.
>
> Agreed it's not a good use case. Unless/until pkcs1 is supported, I
> don't see how you can use it for all of the test cases. Plus as
> evidenced by Ubuntu's new cert, it requires validating the library.
Of course it requires validating the library, validating the
cryptography implementation is what FIPS is for. libcrypto.so can never
be outside the boundary, unless you turn it off at runtime ...
The problems are rather that libcrypto is not instrumented to enforce
KAT tests are executed before it allows operation (crypto-API did this
via test manager) and does not provide an indicator (or blocks)
unapproved algorithms ...
Simo.
--
Simo Sorce
Distinguished Engineer
RHEL Crypto Team
Red Hat, Inc
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).