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;
prev parent reply other threads:[~2026-11-12 11:37 UTC|newest]
Thread overview: 44+ 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-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-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 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 22:41 ` netdev-bot+sashiko
2026-11-12 11:53 ` 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-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-10 10:20 ` [PATCH net-next v1 08/11] eth: fbnic: Support XDP redirect Björn Töpel
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 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 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