All of lore.kernel.org
 help / color / mirror / Atom feed
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

  reply	other threads:[~2026-10-17 17:41 UTC|newest]

Thread overview: 49+ 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-15 18:46   ` sashiko-bot
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-15 18:46   ` sashiko-bot
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-15 18:46   ` sashiko-bot
2026-10-17  3:06   ` netdev-bot+sashiko
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.