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;
next prev parent reply other threads:[~2026-11-12 11:37 UTC|newest]
Thread overview: 62+ 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-13 0:21 ` 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 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-12 19:51 ` Björn Töpel
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-12 19:57 ` Björn Töpel
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]
2026-11-12 20:03 ` Björn Töpel
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 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.