BPF List
 help / color / mirror / Atom feed
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: "Björn Töpel" <bjorn@kernel.org>
Cc: Magnus Karlsson <magnus.karlsson@intel.com>,
	Stanislav Fomichev <sdf@fomichev.me>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Simon Horman <horms@kernel.org>, Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	Alexander Duyck <alexanderduyck@fb.com>, <kernel-team@meta.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"Jesper Dangaard Brouer" <hawk@kernel.org>,
	Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	John Fastabend <john.fastabend@gmail.com>,
	Pavel Begunkov <asml.silence@gmail.com>,
	Jens Axboe <axboe@kernel.dk>, Andrii Nakryiko <andrii@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	Jiri Olsa <jolsa@kernel.org>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	Ihor Solodrai <ihor.solodrai@linux.dev>, <netdev@vger.kernel.org>,
	<bpf@vger.kernel.org>, <io-uring@vger.kernel.org>,
	Mina Almasry <almasrymina@google.com>,
	"Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>,
	Weiming Shi <bestswngs@gmail.com>,
	Nikolay Aleksandrov <razor@blackwall.org>,
	David Wei <dw@davidwei.uk>,
	Alexander Lobakin <aleksander.lobakin@intel.com>,
	<linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Stuart Clark <stuclar@meta.com>
Subject: Re: [PATCH net-next v1 11/11] eth: fbnic: Support AF_XDP page pool zero copy
Date: Thu, 12 Nov 2026 12:37:09 +0100	[thread overview]
Message-ID: <avWk5as19fvZoEJA@boxer> (raw)
In-Reply-To: <20261110102039.1002605-12-bjorn@kernel.org>

On Tue, Nov 10, 2026 at 11:20:32AM +0100, Björn Töpel wrote:
> Header and payload rings share one provider page pool, so refills even
> them out, and a short pool does not starve one of them. Payload
> buffers start at chunk offset 0, and the UMEM headroom rules require
> headroom only in the first buffer. A chunk is one 4 KiB device page,
> also with larger kernel pages, so rings fed by the provider post one
> descriptor per chunk.
> 
> Socket TX shares the XDP TX ring and runs after RX: XDP_TX drops
> frames that do not fit, while socket descriptors can wait. The TX
> need_wakeup flag stays set, as for ice, since clearing it can miss the
> last wakeup.
> 
> Signed-off-by: Björn Töpel <bjorn@kernel.org>
> ---
>  Documentation/networking/af_xdp.rst           |  58 +++
>  .../net/ethernet/meta/fbnic/fbnic_netdev.c    |  18 +
>  drivers/net/ethernet/meta/fbnic/fbnic_txrx.c  | 428 ++++++++++++++----
>  drivers/net/ethernet/meta/fbnic/fbnic_txrx.h  |  25 +-
>  4 files changed, 446 insertions(+), 83 deletions(-)
> 
> diff --git a/Documentation/networking/af_xdp.rst b/Documentation/networking/af_xdp.rst
> index e73a0005e169..f152ae8812d1 100644
> --- a/Documentation/networking/af_xdp.rst
> +++ b/Documentation/networking/af_xdp.rst
> @@ -346,6 +346,64 @@ Note that a UMEM can be shared between sockets on the same queue id
>  and device, as well as between queues on the same device and between
>  devices at the same time.
>  
> +Zero-copy through page pool
> +---------------------------
> +
> +Some drivers, for example fbnic, receive into the UMEM through a page
> +pool memory provider instead of their own allocator. The socket API
> +does not change: zero-copy mode is selected as before, and XDP_OPTIONS
> +reports it.
> +
> +The requirements are:
> +
> +* Aligned chunks of a size the driver supports, 4 KiB for fbnic.
> +* The queue id has an RX queue, also for a socket that only transmits.
> +  Such a socket needs the FILL and COMPLETION rings, like any other.
> +* The driver accepts the headroom, MTU and XDP program. fbnic accepts
> +  a UMEM headroom of 0, 128 or 256 bytes. An MTU larger than its header
> +  buffer needs XDP_USE_SG, and frags support in an XDP program. The
> +  first buffer of a larger frame may hold only its headers, and the
> +  other buffers start at offset 0 of their chunk. Such a frame can take
> +  one chunk more than in copy mode.
> +
> +If the device cannot do zero-copy for the socket, a bind with
> +XDP_ZEROCOPY fails with EOPNOTSUPP, while a bind without it falls back
> +to copy mode. MTU and XDP program changes that a bound socket cannot
> +handle are refused.
> +
> +Binding restarts the RX queue. The queue takes chunks from the FILL
> +ring and returns them on the RX ring. A FILL entry for a chunk that
> +the RX side still owns is dropped; TX chunks stay with userspace until
> +their completion, as before. XDP_PASS copies the packet. Redirects to
> +anything but a socket copy single-buffer packets and drop others. A
> +redirect to a socket of another queue fails, and generic XDP cannot
> +redirect to the socket.
> +
> +When the queue has no chunks left to post, RX waits for the FILL ring.
> +With XDP_USE_NEED_WAKEUP, the flag on the FILL ring stays set, and
> +userspace must call poll(), or recvfrom() with an RX ring or sendto()
> +with a TX ring, after it posts entries. Without the flag, the queue
> +polls the FILL ring, which costs CPU time while the ring is empty.
> +Post FILL entries before bind() if possible.
> +
> +A driver supports this mode when it:
> +
> +* uses netmem for header buffers and XDP_TX, and handles page pools
> +  whose buffers cannot be split (see page_pool_supports_frag()),
> +* selects the provider with PP_FLAG_MEM_PROVIDER and pp_rx_role for
> +  one page pool of each queue, and honours the rx_headroom queue
> +  configuration,
> +* calls page_pool_refill_done() after each refill,
> +* sends socket TX descriptors from the NAPI of the RX queue, with
> +  xsk_tx_peek_release_desc_batch() for the pool that xsk_rxq_pool()
> +  returns,
> +* advertises NETDEV_XDP_ACT_XSK_ZEROCOPY and xdp_zc_max_segs,
> +* checks the setup in XDP_VALIDATE_XSK_POOL, and sets xsk_page_pool
> +  in its netdev_queue_mgmt_ops.
> +
> +The core schedules that NAPI for RX and TX wakeups, so no
> +ndo_xsk_wakeup is needed.
> +
>  XDP_USE_NEED_WAKEUP bind flag
>  -----------------------------
>  
> diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> index ae2585508690..8cb5b5b93c70 100644
> --- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> +++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
> @@ -5,6 +5,7 @@
>  #include <linux/ipv6.h>
>  #include <linux/types.h>
>  #include <net/netdev_queues.h>
> +#include <net/xdp_sock_drv.h>
>  
>  #include "fbnic.h"
>  #include "fbnic_netdev.h"
> @@ -276,6 +277,7 @@ static int fbnic_set_mac(struct net_device *netdev, void *p)
>  static int fbnic_change_mtu(struct net_device *dev, int new_mtu)
>  {
>  	struct fbnic_net *fbn = netdev_priv(dev);
> +	int err;
>  
>  	if (fbnic_check_split_frames(fbn->xdp_prog, new_mtu, fbn->hds_thresh)) {
>  		dev_err(&dev->dev,
> @@ -285,6 +287,13 @@ static int fbnic_change_mtu(struct net_device *dev, int new_mtu)
>  		return -EINVAL;
>  	}
>  
> +	err = xsk_validate_dev(dev, new_mtu, NULL, XDP_MODE_DRV, NULL);
> +	if (err) {
> +		dev_err(&dev->dev, "MTU %d does not fit a bound AF_XDP socket\n",
> +			new_mtu);
> +		return err;
> +	}
> +
>  	WRITE_ONCE(dev->mtu, new_mtu);
>  
>  	return 0;
> @@ -538,6 +547,13 @@ static int fbnic_bpf(struct net_device *netdev, struct netdev_bpf *bpf)
>  {
>  	struct bpf_prog *prog = bpf->prog, *prev_prog;
>  	struct fbnic_net *fbn = netdev_priv(netdev);
> +	const struct xsk_rx_check *check;
> +
> +	if (bpf->command == XDP_VALIDATE_XSK_POOL) {

do you really need a separate command here? why not rely on existing
XDP_SETUP_XSK_POOL ?

here it doesn't look like things being validated are something unique that
you could not check during XDP_SETUP_XSK_POOL and XDP_SETUP_PROG.

Overall, +400 lines for zc pp-based support...not sure what I was
expecting and I know we need Tx side implementation.

However, I am wondering if better example for this change set would be the
driver that already supports pp *and* carries the separate ZC data path
(ekhm, see ice?). Then you could show case at least in diffstat how much
less work is needed for AF_XDP support.

> +		check = bpf->xsk_check.check;
> +		prog = check->prog ? : READ_ONCE(fbn->xdp_prog);
> +		return fbnic_xsk_validate(check, prog, bpf->xsk_check.extack);
> +	}
>  
>  	if (bpf->command != XDP_SETUP_PROG)
>  		return -EINVAL;
> @@ -825,6 +841,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
>  	netdev->xdp_features = NETDEV_XDP_ACT_BASIC |
>  			       NETDEV_XDP_ACT_REDIRECT |
>  			       NETDEV_XDP_ACT_RX_SG;
> +	netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
> +	netdev->xdp_zc_max_segs = FBNIC_MAX_RX_BUFS;
>  
>  	netdev->min_mtu = IPV6_MIN_MTU;
>  	netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN;

      parent reply	other threads:[~2026-11-12 11:37 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 10:20 [PATCH net-next v1 00/11] xsk: Zero copy through page-pool memory providers Björn Töpel
2026-11-10 10:20 ` [PATCH net-next v1 01/11] net: Get skb fragment addresses through netmem Björn Töpel
2026-11-12  8:32   ` saeed bishara
2026-11-12 13:57     ` Björn Töpel
2026-11-10 10:20 ` [PATCH net-next v1 02/11] net: Add memory provider capabilities Björn Töpel
2026-11-10 22:19   ` Stanislav Fomichev
2026-11-11 12:41     ` Björn Töpel
2026-11-11 23:01       ` Stanislav Fomichev
2026-11-12 14:01         ` Björn Töpel
2026-11-11 10:22   ` sashiko-bot
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-10 10:20 ` [PATCH net-next v1 03/11] xdp: Copy buffers with restricted lifetime Björn Töpel
2026-11-10 22:32   ` Stanislav Fomichev
2026-11-11 13:27     ` Björn Töpel
2026-11-11 23:05       ` Stanislav Fomichev
2026-11-11 10:22   ` sashiko-bot
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-10 10:20 ` [PATCH net-next v1 04/11] xsk: Allocate UMEM chunks through page_pool Björn Töpel
2026-11-10 15:08   ` Magnus Karlsson
2026-11-11 13:51     ` Björn Töpel
2026-11-10 23:02   ` Stanislav Fomichev
2026-11-11 13:59     ` Björn Töpel
2026-11-11 23:09       ` Stanislav Fomichev
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-10 10:20 ` [PATCH net-next v1 05/11] xsk: Install UMEM page pool providers in the core Björn Töpel
2026-11-10 23:50   ` Stanislav Fomichev
2026-11-11 14:01     ` Björn Töpel
2026-11-11  8:59   ` Magnus Karlsson
2026-11-11 19:26     ` Björn Töpel
2026-11-12  8:08       ` Magnus Karlsson
2026-11-11 10:22   ` sashiko-bot
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-12 11:53   ` Maciej Fijalkowski
2026-11-12 14:48     ` Björn Töpel
2026-11-12 15:43       ` Maciej Fijalkowski
2026-11-10 10:20 ` [PATCH net-next v1 06/11] page_pool: Coordinate refill with memory providers Björn Töpel
2026-11-10 23:51   ` Stanislav Fomichev
2026-11-11 19:37     ` Björn Töpel
2026-11-11 23:13       ` Stanislav Fomichev
2026-11-12 14:53         ` Björn Töpel
2026-11-11 10:22   ` sashiko-bot
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-10 10:20 ` [PATCH net-next v1 07/11] xsk: Deliver provider chunks without copying Björn Töpel
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-11 23:20   ` Stanislav Fomichev
2026-11-12 15:10     ` Björn Töpel
2026-11-12 12:17   ` Maciej Fijalkowski
2026-11-10 10:20 ` [PATCH net-next v1 08/11] eth: fbnic: Support XDP redirect Björn Töpel
2026-11-11 10:22   ` sashiko-bot
2026-11-10 10:20 ` [PATCH net-next v1 09/11] eth: fbnic: Use netmem for RX headers and XDP_TX Björn Töpel
2026-11-10 10:20 ` [PATCH net-next v1 10/11] eth: fbnic: Support RX buffers it cannot split Björn Töpel
2026-11-11 10:22   ` sashiko-bot
2026-11-11 21:45   ` Dimitri Daskalakis
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-10 10:20 ` [PATCH net-next v1 11/11] eth: fbnic: Support AF_XDP page pool zero copy Björn Töpel
2026-11-11 10:22   ` sashiko-bot
2026-11-11 22:41   ` netdev-bot+sashiko
2026-11-12 11:37   ` Maciej Fijalkowski [this message]

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=avWk5as19fvZoEJA@boxer \
    --to=maciej.fijalkowski@intel.com \
    --cc=aleksander.lobakin@intel.com \
    --cc=alexanderduyck@fb.com \
    --cc=almasrymina@google.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrii@kernel.org \
    --cc=asml.silence@gmail.com \
    --cc=ast@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=bestswngs@gmail.com \
    --cc=bjorn@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=corbet@lwn.net \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=dw@davidwei.uk \
    --cc=eddyz87@gmail.com \
    --cc=edumazet@kernel.org \
    --cc=emil@etsalapatis.com \
    --cc=hawk@kernel.org \
    --cc=horms@kernel.org \
    --cc=ihor.solodrai@linux.dev \
    --cc=ilias.apalodimas@linaro.org \
    --cc=io-uring@vger.kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=magnus.karlsson@intel.com \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=mike.marciniszyn@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=razor@blackwall.org \
    --cc=rdunlap@infradead.org \
    --cc=sdf@fomichev.me \
    --cc=skhan@linuxfoundation.org \
    --cc=song@kernel.org \
    --cc=stuclar@meta.com \
    --cc=yonghong.song@linux.dev \
    /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