From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: <tkusters@aweta.nl>
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>,
Przemek Kitszel <przemyslaw.kitszel@intel.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
"Alexei Starovoitov" <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
"Jesper Dangaard Brouer" <hawk@kernel.org>,
John Fastabend <john.fastabend@gmail.com>,
Stanislav Fomichev <sdf@fomichev.me>,
Sven Auhagen <sven.auhagen@voleatech.de>,
Richard Cochran <richardcochran@gmail.com>,
"Kurt Kanzenbach" <kurt@linutronix.de>,
Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>,
<intel-wired-lan@lists.osuosl.org>, <netdev@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <bpf@vger.kernel.org>,
Paul Moses <p@1g4.org>, <stable@vger.kernel.org>
Subject: Re: [PATCH net v5 3/4] igb: do not split AF_XDP zero-copy frames over several Rx buffers
Date: Sat, 7 Nov 2026 17:37:53 +0100 [thread overview]
Message-ID: <au9T4Y1rpxvuEuFv@boxer> (raw)
In-Reply-To: <20261104-igb-rx-ts-fix-v5-3-bf4b4367129a@aweta.nl>
On Wed, Nov 04, 2026 at 07:40:04AM +0100, Tjerk Kusters via B4 Relay wrote:
> From: Tjerk Kusters <tkusters@aweta.nl>
>
> SRRCTL.BSIZEPKT has a granularity of 1 KiB. For AF_XDP zero-copy rings,
> igb_setup_srrctl() programs xsk_pool_get_rx_frame_size(), which is
> rounded down. With 2 KiB UMEM chunks and the default headroom this is
> 1792 bytes, so the hardware buffer becomes 1 KiB and a full-size frame
> spans two Rx buffers. igb_clean_rx_irq_zc() handles every descriptor as
> a complete frame, so the AF_XDP socket gets such a frame as two
> packets, the second one without headers. With Rx timestamping enabled,
> the timestamp header is also stripped from the second buffer, and a
> short final buffer makes the size wrap.
>
> Program the same buffer size as for the other rings, 2 KiB or 3 KiB.
> This depends on "igb: do not let XDP frames span more than one Rx
> buffer": the receive length limit set there while XDP is attached keeps
> the hardware from writing more than the frame plus the timestamp header
> into the larger buffer. Without it, the hardware can write past the XSK
> frame.
>
> Refuse an XSK pool whose frame size cannot hold that, and an MTU change
> that would no longer fit a bound pool, also while no XDP program is
> attached. The current MTU is checked rather than the largest XDP MTU,
> as igb allows XDP up to MTU 3030 and that would rule out 2 KiB chunks.
> A pool that still does not fit when the ring is configured, for example
> because its queue was hidden by SR-IOV during an MTU change, is not used
> in zero-copy mode, see igb_xsk_pool(); its Tx then fails with EINVAL
> until the pool is bound again.
I would rather return -EBUSY when enabling VFs on queues with active
xsk_pool. Seems igb sort of steal queues from PF?
We do this in core when xsk_pool enabled queue would get wiped out via
ethtool -L shrinking the queue count.
>
> This is the igb counterpart of the igc XSK buffer change.
>
> Tested on an I350 with xdpsock from bpf-examples in rxdrop zero-copy
> mode on one queue, Rx timestamping on and 1514-byte frames from the
> peer. With 2 KiB chunks, the receive descriptors went from about two
> per frame to one per frame; 98-byte frames and 4 KiB chunks were one
> per frame with and without this patch. At MTU 3000, 4 KiB chunks
> receive 3014-byte frames in one buffer. A 2 KiB chunk pool at MTU 3000
> was refused by the new check on the 6.14.9 test kernel; current kernels
> already refuse it in xp_assign_dev(). There, with 2 KiB chunks and the
> default headroom, the new check refuses MTU 1751 to 1766, which the core
> accepts.
>
> Link: https://lore.kernel.org/all/20261028083344.3047350-3-p@1g4.org/
> Fixes: 2c6196013f84 ("igb: Add AF_XDP zero-copy Rx support")
> Cc: stable@vger.kernel.org
> Suggested-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
> Signed-off-by: Tjerk Kusters <tkusters@aweta.nl>
> ---
> drivers/net/ethernet/intel/igb/igb.h | 9 +++++++++
> drivers/net/ethernet/intel/igb/igb_main.c | 28 +++++++++++++++++++++++++---
> drivers/net/ethernet/intel/igb/igb_xsk.c | 19 ++++++++++++++++++-
> 3 files changed, 52 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
> index 0fff1df81b7b..0495c02544d6 100644
> --- a/drivers/net/ethernet/intel/igb/igb.h
> +++ b/drivers/net/ethernet/intel/igb/igb.h
> @@ -856,6 +856,15 @@ int igb_add_mac_steering_filter(struct igb_adapter *adapter,
> int igb_del_mac_steering_filter(struct igb_adapter *adapter,
> const u8 *addr, u8 queue, u8 flags);
>
> +/* XDP does not support frames that span more than one Rx buffer, so a
> + * frame plus the inline Rx timestamp header must fit in one XSK buffer.
> + */
> +static inline bool igb_xsk_frame_fits(struct xsk_buff_pool *pool,
> + int max_frame)
> +{
> + return max_frame + IGB_TS_HDR_LEN <= xsk_pool_get_rx_frame_size(pool);
> +}
> +
> struct xsk_buff_pool *igb_xsk_pool(struct igb_adapter *adapter,
> struct igb_ring *ring);
> int igb_xsk_pool_setup(struct igb_adapter *adapter,
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index cf9911137bd3..b286adedad5d 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -4833,9 +4833,13 @@ void igb_setup_srrctl(struct igb_adapter *adapter, struct igb_ring *ring)
> u32 srrctl = 0;
> u32 buf_size;
>
> - if (ring->xsk_pool)
> - buf_size = xsk_pool_get_rx_frame_size(ring->xsk_pool);
> - else if (ring_uses_large_buffer(ring))
> + /* SRRCTL.BSIZEPKT has a 1 KiB granularity, so programming the XSK
> + * frame size would round it down and split frames over several
> + * buffers. XSK rings use the same buffer size as the other rings.
> + * While XDP is attached, the receive length limit keeps frames
> + * within the XSK frame, see igb_xsk_frame_fits().
> + */
> + if (ring_uses_large_buffer(ring))
> buf_size = IGB_RXBUFFER_3072;
> else
> buf_size = IGB_RXBUFFER_2048;
> @@ -6775,6 +6779,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
> {
> struct igb_adapter *adapter = netdev_priv(netdev);
> int max_frame = new_mtu + IGB_ETH_PKT_HDR_PAD;
> + int i;
>
> if (igb_xdp_is_enabled(adapter) &&
> !igb_xdp_frame_fits(adapter, max_frame)) {
> @@ -6788,6 +6793,23 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
> if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN))
> max_frame = ETH_FRAME_LEN + ETH_FCS_LEN;
>
> + /* the frame must fit the buffers of a bound XSK pool, also while no
> + * XDP program is attached, as attaching one does not check it again
> + */
> + for (i = 0; i < adapter->num_rx_queues; i++) {
> + struct xsk_buff_pool *pool = xsk_get_pool_from_qid(netdev, i);
> +
> + if (!pool || !pool->dev)
> + continue;
> +
> + if (!igb_xsk_frame_fits(pool, max_frame)) {
> + netdev_warn(adapter->netdev,
> + "Requested MTU size is not supported with AF_XDP. Frame size is %d\n",
> + max_frame);
> + return -EINVAL;
> + }
> + }
> +
> while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
> usleep_range(1000, 2000);
>
> diff --git a/drivers/net/ethernet/intel/igb/igb_xsk.c b/drivers/net/ethernet/intel/igb/igb_xsk.c
> index ce4a7b58cad2..fb04df82272a 100644
> --- a/drivers/net/ethernet/intel/igb/igb_xsk.c
> +++ b/drivers/net/ethernet/intel/igb/igb_xsk.c
> @@ -91,7 +91,20 @@ struct xsk_buff_pool *igb_xsk_pool(struct igb_adapter *adapter,
> if (!igb_xdp_is_enabled(adapter))
> return NULL;
>
> - return (pool && pool->dev) ? pool : NULL;
> + if (!pool || !pool->dev)
> + return NULL;
> +
> + /* the MTU check in igb_change_mtu() does not see a pool on a queue
> + * that was hidden at the time, for example by SR-IOV
> + */
> + if (!igb_xsk_frame_fits(pool, adapter->max_frame_size)) {
> + netdev_warn_once(adapter->netdev,
> + "XSK frame size is too small for the MTU, queue %d is not used in zero-copy mode\n",
> + qid);
> + return NULL;
> + }
> +
> + return pool;
> }
>
> static int igb_xsk_pool_enable(struct igb_adapter *adapter,
> @@ -110,6 +123,10 @@ static int igb_xsk_pool_enable(struct igb_adapter *adapter,
> qid >= netdev->real_num_tx_queues)
> return -EINVAL;
>
> + /* igb_change_mtu() keeps this true while the pool is bound */
> + if (!igb_xsk_frame_fits(pool, adapter->max_frame_size))
> + return -EOPNOTSUPP;
> +
> err = xsk_pool_dma_map(pool, &adapter->pdev->dev, IGB_RX_DMA_ATTR);
> if (err)
> return err;
>
> --
> 2.27.0
>
>
next prev parent reply other threads:[~2026-11-07 16:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 6:40 [PATCH net v5 0/4] igb: only strip the Rx timestamp header from the first buffer of a frame Tjerk Kusters via B4 Relay
2026-11-04 6:40 ` [PATCH net v5 1/4] igb: do not let XDP frames span more than one Rx buffer Tjerk Kusters via B4 Relay
2026-11-04 6:40 ` [PATCH net v5 2/4] igb: only strip Rx timestamp header on the first buffer of a frame Tjerk Kusters via B4 Relay
2026-11-04 6:40 ` [PATCH net v5 3/4] igb: do not split AF_XDP zero-copy frames over several Rx buffers Tjerk Kusters via B4 Relay
2026-11-07 16:37 ` Maciej Fijalkowski [this message]
2026-11-04 6:40 ` [PATCH net v5 4/4] igb: drop AF_XDP zero-copy frames that span " Tjerk Kusters via B4 Relay
2026-11-07 16:00 ` Maciej Fijalkowski
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=au9T4Y1rpxvuEuFv@boxer \
--to=maciej.fijalkowski@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=kurt@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=p@1g4.org \
--cc=pabeni@redhat.com \
--cc=przemyslaw.kitszel@intel.com \
--cc=richardcochran@gmail.com \
--cc=sdf@fomichev.me \
--cc=sriram.yagnaraman@ericsson.com \
--cc=stable@vger.kernel.org \
--cc=sven.auhagen@voleatech.de \
--cc=tkusters@aweta.nl \
/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
all inboxes | Powered by JetHome®