From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: <netdev-bot+sashiko@kernel.org>
Cc: <netdev@vger.kernel.org>, <bpf@vger.kernel.org>,
<magnus.karlsson@intel.com>, <stfomichev@gmail.com>,
<kuba@kernel.org>, <pabeni@redhat.com>,
<tushar.vyavahare@intel.com>, <kerneljasonxing@gmail.com>,
<bjorn@kernel.org>
Subject: Re: [PATCH v3 net-next 11/15] selftests: xsk: add a hardware mode to xskxceiver
Date: Sat, 17 Oct 2026 19:40:54 +0200 [thread overview]
Message-ID: <atOzJh0xuXP3fiw0@boxer> (raw)
In-Reply-To: <179220636945.434549.3726298644003511435@kernel.org>
On Sat, Oct 17, 2026 at 03:06:09AM +0000, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 7 potential
> issue(s) to consider.
>
> Critical: 0 · High: 0 · Medium: 3 · Low: 4
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
>
> - [Medium] A hardware SKB-mode endpoint still gates every multi-buffer
> case on XSK_CAP_MBUF.
> - [Medium] The comment in wait_link_up() says 'Each endpoint makes its
> changes before it is ready', but the TX endpoint creates its UMEM and…
> - [Medium] cleanup_iface() in xskxceiver.c now fails the endpoint when
> xsk_set_mtu() cannot restore orig_mtu, but it still ignores the return…
> - [Low] At this commit, hardware mode switches the test frames to
> UDP/IPv4, but the XDP programs (xsk_def_prog, xsk_xdp_drop,…
> - [Low] testapp_too_many_frags() builds the stream from
> max_frags_override no matter which mode the local TX endpoint runs in.
> - [Low] parse_command_line() rejects --listen and --max-frags without
> --hw, but it silently accepts --udp-src, --udp-dst, --udp-port and…
> - [Low] In hardware mode, sync_endpoints() exchanges READY and then each
> endpoint calls wait_link_up() on its own interface only, once.
>
> --
>
> selftests: xsk: add a hardware mode to xskxceiver
>
> This commit adds a --hw mode to xskxceiver. In this mode,
> drivers/net/hw/xsk.py can run AF_XDP cases between a zero-copy DUT and an
> SKB-mode remote over a physical link, using UDP/IPv4 frames between the
> real MACs. It also adds --queue, --listen and --max-frags, waits for the
> link after endpoint synchronization, defaults cases to ETH_DATA_LEN, and
> restores the original MTU in cleanup_iface().
>
> > diff --git a/tools/testing/selftests/net/lib/xsk/test_xsk.c b/tools/testing/selftests/net/lib/xsk/test_xsk.c
> > index f67a32c0260a3..a280956d53f4a 100644
> > --- a/tools/testing/selftests/net/lib/xsk/test_xsk.c
> > +++ b/tools/testing/selftests/net/lib/xsk/test_xsk.c
>
> [ ... ]
>
> > @@ -84,11 +97,72 @@ static void write_payload(void *dest, u32 pkt_nb, u32 start, u32 size)
>
> [ ... ]
>
> > memcpy(eth_hdr->h_dest, xsk->dst_mac, ETH_ALEN);
> > memcpy(eth_hdr->h_source, xsk->src_mac, ETH_ALEN);
> > - eth_hdr->h_proto = htons(ETH_P_LOOPBACK);
> > + if (!udp_packets) {
> > + eth_hdr->h_proto = htons(ETH_P_LOOPBACK);
> > + return;
> > + }
> > +
> > + eth_hdr->h_proto = htons(ETH_P_IP);
>
> [Severity: Low]
> At this commit hardware mode sends UDP/IPv4 test frames, but xsk_def_prog,
> xsk_xdp_drop and xsk_xdp_populate_metadata in xsk_xdp_progs.bpf.c still act
> on every frame received on the queue:
>
> return bpf_redirect_map(&xsk, 0, XDP_DROP);
>
> On a physical link, could non-test traffic such as IPv6 ND/MLD or LLDP
> reach the socket on the bound queue? Could it also shift drop_idx or the
> metadata count?
>
> This is resolved later in the series. The commit "selftests: xsk: pass
> non-test traffic to the stack in hardware mode" adds is_test_packet(), and
> xsk.py adds ntuple steering. drivers/net/hw/xsk.py does not exist yet at
> this commit, so no runner can hit the gap here.
>
> [ ... ]
>
> > @@ -1703,14 +1829,36 @@ static int testapp_validate_rx_endpoint(struct test_spec *test,
>
> [ ... ]
>
> > +/* An MTU or XDP change can reset a NIC, which takes the link down on both
> > + * hosts. Each endpoint makes its changes before it is ready, so once both are,
> > + * wait for the local link before any traffic.
> > + */
>
> [Severity: Medium]
> Does this hold for the TX endpoint? worker_testapp_validate_tx() runs the
> barrier first, and only creates the UMEM and the XDP_ZEROCOPY socket after
> it:
>
> worker_testapp_validate_tx()
> sync_endpoints()
> xsk_peer_ready()
> wait_link_up()
> testapp_validate_tx_endpoint()
> thread_common_ops()
> xsk_configure()
> xsk_socket__create()
> send_pkts()
>
> The RX side binds in testapp_prepare_rx_endpoint() before sync_endpoints(),
> so only the TX bind happens after the barrier.
corrected comment in v4
>
> On some zero-copy drivers the pool setup restarts the interface. For
> example, dpaa2_xsk_enable_pool() in dpaa2-xsk.c does:
>
> up = netif_running(dev);
> if (up)
> dev_close(dev);
> ...
> if (up)
> dev_open(dev, NULL);
>
> dpaa2 advertises NETDEV_XDP_ACT_XSK_ZEROCOPY. Can send_pkts() then
> transmit while the carrier is still coming back? That would lose the
> frames and leave RX to hit the 20s timeout in hardware TX-role cases. The
> code is the same at the end of the series.
>
> > +static int wait_link_up(struct test_spec *test)
>
> [ ... ]
>
> > static int sync_endpoints(struct test_spec *test)
> > {
> > int err = xsk_peer_ready(ctrl_peer);
> >
> > - if (err)
> > + if (err) {
> > ksft_print_msg("Endpoint synchronization failed at step %u: %d (%s)\n",
> > test->current_step, err, strerror(-err));
> > - return err;
> > + return err;
> > + }
> > + return hw_test ? wait_link_up(test) : 0;
>
> [Severity: Low]
> Each endpoint checks only its own interface here, and nothing comes after
> the link check. TX goes into send_pkts() as soon as its own ETHTOOL_GLINK
> reads up, and pacing_tx_sync() does not block. xsk_wait_link_up() returns
> on the first sample that reads up:
>
> if (err || edata.data)
> return err;
>
> Suppose the RX host's driver applies an MTU, XDP or ring change through an
> asynchronous reset, and the link drops only after READY was delivered.
> Could TX then act on a stale up state and transmit into the reset?
>
> At the end of the series the control connection runs over the tested link.
> That covers drivers that reset synchronously, which is what ice, i40e,
> mlx5, igb and ixgbe do. No mainline driver with an asynchronous reset was
> identified, so this may only be theoretical.
>
> [ ... ]
>
> > @@ -2284,7 +2444,9 @@ int testapp_too_many_frags(struct test_spec *test)
> > u32 max_frags, i;
> > int ret = TEST_FAILURE;
> >
> > - if (test->mode == TEST_MODE_ZC) {
> > + if (max_frags_override) {
> > + max_frags = max_frags_override;
> > + } else if (test->mode == TEST_MODE_ZC) {
>
> [Severity: Low]
> The override replaces the limit no matter which mode the transmitting
> endpoint runs in. If the SKB-mode remote were TX with the DUT's zero-copy
> limit, wouldn't the copy-mode TX path send the "too many" packet anyway?
>
> At the end of the series TOO_MANY_FRAGS is listed only in hw_tx_tests[].
> xsk.py always runs it with the zero-copy DUT as TX, so the mismatch does
> not appear reachable there. Would a short comment noting that assumption
> next to the override help?
>
> [ ... ]
>
> > @@ -2378,6 +2540,7 @@ static int detect_ifobj_caps(struct ifobject *ifobj)
> > if (query_opts.feature_flags & NETDEV_XDP_ACT_RX_SG)
> > ifobj_set_cap(ifobj, XSK_CAP_MBUF);
> > if (query_opts.feature_flags & NETDEV_XDP_ACT_XSK_ZEROCOPY) {
> > + ifobj_set_cap(ifobj, XSK_CAP_ZC_ADVERTISED);
>
> [Severity: Medium]
> A hardware SKB-mode endpoint still gates every multi-buffer case on
> XSK_CAP_MBUF. That cap comes from the native driver NETDEV_XDP_ACT_RX_SG
> flag, queried with XDP_FLAGS_DRV_MODE. In __testapp_validate_traffic():
>
> mbuf_cap = test->mode == TEST_MODE_ZC ? XSK_CAP_MBUF_ZC :
> XSK_CAP_MBUF;
>
> if (!ifobj_has_cap(ifobj1, mbuf_cap) ||
> (ifobj2 && !ifobj_has_cap(ifobj2, mbuf_cap))) {
> ...
> return TEST_SKIP;
> }
>
> Generic XDP does not need native RX_SG for xdp.frags programs.
> netif_receive_generic_xdp() handles non-linear skbs through
> skb_cow_data_for_xdp().
>
> Take a remote NIC that does not set NETDEV_XDP_ACT_RX_SG, such as igb, igc
> or ixgbe. The remote then skips SEND_RECEIVE_9K_PACKETS, UNALIGNED_9K,
> XDP_METADATA_COPY_MULTI_BUFF, the ADJUST_TAIL_*_MULTI_BUFF and
> *_INV_DESC_MULTI_BUFF cases, and TOO_MANY_FRAGS. The zero-copy DUT checks
> XSK_CAP_MBUF_ZC instead and continues.
>
> Does the DUT then fail in sync_endpoints() once the remote closes the
> control channel? At the end of the series xsk.py reports this one-sided
> skip as SKIP, so multi-buffer coverage is lost whenever the remote is a
> non-SG NIC.
>
> The commit message says:
>
> - a hardware endpoint probes only the mode it runs in, taking zero-copy
> support from NETDEV_XDP_ACT_XSK_ZEROCOPY
>
> Should XSK_CAP_MBUF follow the same rule for an SKB-mode endpoint?
I assume this implies mixed NICs setup, say ice<->mlx5. mlx5 supports
RX_SG but not ZC_MBUF, so mbuf cases for ice as DUT will run.
I view this as corner case of funky setup, better to be addressed but
again it is rather minor, I haven't seen in netdev CI a setup which would
be currently offended by this.
>
> [ ... ]
>
> > diff --git a/tools/testing/selftests/net/lib/xsk/xskxceiver.c b/tools/testing/selftests/net/lib/xsk/xskxceiver.c
> > index 769718cad8cd7..7044822f23c0a 100644
> > --- a/tools/testing/selftests/net/lib/xsk/xskxceiver.c
> > +++ b/tools/testing/selftests/net/lib/xsk/xskxceiver.c
>
> [ ... ]
>
> > @@ -306,6 +378,10 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
> > !*opt_peer_host || !opt_peer_port || opt_run_test == RUN_ALL_TESTS ||
> > opt_mode == TEST_MODE_ALL)
> > print_usage(argv);
> > + if (opt_hw && (!opt_udp_src || !opt_udp_dst || !opt_udp_port || !opt_peer_mac))
> > + print_usage(argv);
> > + if ((opt_listen || opt_max_frags) && !opt_hw)
> > + print_usage(argv);
> > }
>
> [Severity: Low]
> This isn't a bug, but --udp-src, --udp-dst, --udp-port and --peer-mac are
> accepted without --hw and then silently ignored. main() calls
> xsk_set_udp_packet_format() only under opt_hw, and setup_peer() copies
> opt_peer_mac only under opt_hw.
>
> Should these options be rejected without --hw, like --listen and
> --max-frags are? print_usage() also describes them as if they always apply.
>
> [ ... ]
>
> > @@ -401,8 +487,16 @@ static void cleanup_iface(struct ifobject *ifobj)
> > xsk_detach_xdp_program(ifobj->ifindex,
> > ifobj->mode == TEST_MODE_SKB ?
> > XDP_FLAGS_SKB_MODE : XDP_FLAGS_DRV_MODE);
> > + /* After the detach, as an attached program can cap the MTU. */
> > + if (ifobj->dev_mtu != ifobj->orig_mtu) {
> > + err = xsk_set_mtu(ifobj->ifindex, ifobj->orig_mtu);
> > + if (err)
> > + ksft_print_msg("Failed to restore MTU %d on %s\n",
> > + ifobj->orig_mtu, ifobj->ifname);
> > + }
> > unload:
> > xsk_unload_xdp_programs(ifobj);
> > + return err;
> > }
>
> [Severity: Medium]
> A failed MTU restore now fails the endpoint. The ring restore just above
> this hunk still ignores its return value:
>
> if (ifobj_has_cap(ifobj, XSK_CAP_HW_RING))
> hw_ring_size_reset(ifobj);
>
> set_hw_ring_size() can fail with a non-EBUSY error, or after the EBUSY
> retries run out. In that case hw_ring_size_reset() keeps the changed sizes
> for a later reset. No later reset happens, because the process exits, and
> the endpoint still reports PASS.
>
> This patch makes that more likely. __test_spec_init() now resets rings on
> any local ifobj, and testapp_hw_sw_max_ring_size() now sets the receiver's
> rx_pending to rx_max_pending. The final xsk.py relies on the endpoints to
> restore ring sizes.
>
> Can a failed restore leave the NIC with enlarged rings? The next run's
> detect_ifobj_caps() would then record those as set_ring.default_tx and
> set_ring.default_rx. Should the result of hw_ring_size_reset() also feed
> err here?
In v4 the runner sets and restores the rings, not xskxceiver, including
when an endpoint is killed.
>
> --
> Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261014184539.774708-1-maciej.fijalkowski%40intel.com
next prev parent reply other threads:[~2026-10-17 17:41 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 18:45 [PATCH v3 net-next 00/15] selftests: net: migrate AF_XDP test suite over to net Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 01/15] selftests: xsk: factor endpoint work out of pthread wrappers Maciej Fijalkowski
2026-10-15 8:14 ` Björn Töpel
2026-10-14 18:45 ` [PATCH v3 net-next 02/15] selftests: xsk: size the TX UMEM in HW_SW_MAX_RING_SIZE Maciej Fijalkowski
2026-10-15 8:15 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-17 14:40 ` Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 03/15] selftests: xsk: drop the single-interface loopback mode Maciej Fijalkowski
2026-10-15 8:17 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-17 14:50 ` Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 04/15] selftests/bpf: drop the test_progs AF_XDP wrapper Maciej Fijalkowski
2026-10-15 8:18 ` Björn Töpel
2026-10-14 18:45 ` [PATCH v3 net-next 05/15] selftests: net: add a generic rule for BPF skeletons Maciej Fijalkowski
2026-10-15 8:20 ` Björn Töpel
2026-10-14 18:45 ` [PATCH v3 net-next 06/15] selftests: xsk: move the AF_XDP test suite to selftests/net Maciej Fijalkowski
2026-10-15 8:22 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-17 15:31 ` Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 07/15] selftests: xsk: collect interface capabilities in struct xsk_caps Maciej Fijalkowski
2026-10-15 8:27 ` Björn Töpel
2026-10-14 18:45 ` [PATCH v3 net-next 08/15] selftests: xsk: split xskxceiver main() into setup, run and cleanup Maciej Fijalkowski
2026-10-15 8:29 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-14 18:45 ` [PATCH v3 net-next 09/15] selftests: xsk: run one test case per xskxceiver invocation Maciej Fijalkowski
2026-10-15 8:34 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-17 16:04 ` Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 10/15] selftests: xsk: run the RX and TX endpoints in separate processes Maciej Fijalkowski
2026-10-15 9:04 ` Björn Töpel
2026-10-14 18:45 ` [PATCH v3 net-next 11/15] selftests: xsk: add a hardware mode to xskxceiver Maciej Fijalkowski
2026-10-15 9:42 ` Björn Töpel
2026-10-15 10:55 ` Maciej Fijalkowski
2026-10-15 16:03 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-17 17:40 ` Maciej Fijalkowski [this message]
2026-10-14 18:45 ` [PATCH v3 net-next 12/15] selftests: xsk: pass non-test traffic to the stack in hardware mode Maciej Fijalkowski
2026-10-15 10:05 ` Björn Töpel
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-14 18:45 ` [PATCH v3 net-next 13/15] selftests: xsk: list the hardware test cases Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 14/15] selftests: drv-net: test AF_XDP zero-copy with an SKB peer Maciej Fijalkowski
2026-10-15 10:29 ` Björn Töpel
2026-10-15 12:52 ` Maciej Fijalkowski
2026-10-17 3:06 ` netdev-bot+sashiko
2026-10-17 18:50 ` Maciej Fijalkowski
2026-10-14 18:45 ` [PATCH v3 net-next 15/15] selftests: xsk: document generic and hardware endpoint runs Maciej Fijalkowski
2026-10-17 3:06 ` netdev-bot+sashiko
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=atOzJh0xuXP3fiw0@boxer \
--to=maciej.fijalkowski@intel.com \
--cc=bjorn@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=kerneljasonxing@gmail.com \
--cc=kuba@kernel.org \
--cc=magnus.karlsson@intel.com \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stfomichev@gmail.com \
--cc=tushar.vyavahare@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox