From: "Björn Töpel" <bjorn@kernel.org>
To: Magnus Karlsson <magnus.karlsson@gmail.com>
Cc: Magnus Karlsson <magnus.karlsson@intel.com>,
Maciej Fijalkowski <maciej.fijalkowski@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 05/11] xsk: Install UMEM page pool providers in the core
Date: Wed, 11 Nov 2026 11:26:19 -0800 [thread overview]
Message-ID: <875wy3890k.fsf@all.your.base.are.belong.to.us> (raw)
In-Reply-To: <CAJ8uoz2JMEKkzO-V7jtreS9q1Btmo0URosXzBGW7f=jhFnUzxg@mail.gmail.com>
Magnus Karlsson <magnus.karlsson@gmail.com> writes:
> On Tue, 10 Nov 2026 at 11:36, Björn Töpel <bjorn@kernel.org> wrote:
>> diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
>> index 18966bbdb5b7..c620a0c32c17 100644
>> --- a/net/xdp/xsk_buff_pool.c
>> +++ b/net/xdp/xsk_buff_pool.c
>> @@ -104,10 +101,30 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
>> pool->fq = xs->fq_tmp;
>> pool->cq = xs->cq_tmp;
>>
>> - for (i = 0; i < pool->free_heads_cnt; i++) {
>> + return pool;
>> +
>> +out:
>> + xp_destroy(pool);
>> + return NULL;
>> +}
>> +
>> +/* Only copy mode and driver zero copy use heads */
>> +int xp_alloc_heads(struct xsk_buff_pool *pool)
>> +{
>> + struct xdp_buff_xsk *xskb;
>> + u32 i;
>> +
>> + if (pool->heads)
>> + return 0;
>> +
>> + pool->heads = kvzalloc_objs(*pool->heads, pool->heads_cnt);
>> + if (!pool->heads)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < pool->heads_cnt; i++) {
>
> Now I get why you are not reusing the existing xdp_buff_xsk infra, you
> are removing them here for the PP case. Please mention this in the
> cover letter of the previous patch. There might be a good argument for
> it at least in aligned mode. It is wasting memory versus performance.
> Today when memory is expensive and also for umems that are shared
> between many sockets, the current scheme in the xsk_buffer pool for
> aligned mode might not be worth it.
Will do!
> I have two questions for you. What would the performance be if you
> moved the aligned mode over to use the same free_list as unaligned
> mode and then use that in PP? Would reuse more code, but would it be
> fast enough?
>
> If that is not performant, what if you instead decreased the cost of
> the current pre-allocated xskbs in aligned mode by just creating a
> single copy per umem and using those in PP? Might be a good thing for
> regular xsk drivers too these days, but do not know if it will work
> for you.
>
> I do not know if any of these suggestions would work, but I think you
> should examine them as less code paths is generally a good thing. You
> might also improve the non-PP case too by optimizing it for your case!
Neither would help the provider. The page pool hands out net_iovs, so it
needs one per chunk anyway, and the driver brings its own xdp_buff.
net_iov, reuse and state are 69 bytes per chunk, against 128 for an
xdp_buff_xsk; free_list would add those 128 on top. Nor is reuse on the
hot path: the page pool recycles in its own cache and ring, and gives
chunks back only when it is destroyed or its ring is full. The hot path
is the FILL claim and the RX ring flush.
I don't like the reuse[] fixes size tho...
One copy per UMEM doesn't work either: an xdp_buff_xsk holds pool, rxq,
DMA addresses and cb, so it can only be shared by pools of the same
device and queue, and those already share the pool.
For driver ZC I agree, heads add up with a shared UMEM: 32 MB per pool
for 1 GB of 4K chunks. Unaligned mode allocates a head per chunk too,
though, so moving aligned mode to free_heads saves nothing by itself;
heads would have to be sized by the rings. Worth a look, with numbers,
but in a separate series.
>> xskb = &pool->heads[i];
>> xskb->pool = pool;
>> - xskb->xdp.frame_sz = umem->chunk_size - umem->headroom;
>> + xskb->xdp.frame_sz = pool->chunk_size - pool->headroom;
>> INIT_LIST_HEAD(&xskb->list_node);
>> if (pool->unaligned)
>> pool->free_heads[i] = xskb;
>> @@ -115,11 +132,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
>> xp_init_xskb_addr(xskb, pool, (u64)i * pool->chunk_size);
>> }
>>
>> - return pool;
>> -
>> -out:
>> - xp_destroy(pool);
>> - return NULL;
>> + return 0;
>
> Agree with Stan that these changes should be in a separate commit.
> Think also about if it would make sense to put your page_pool changes
> in yet another commit.
ACK!
>> }
>>
>> void xp_set_rxq_info(struct xsk_buff_pool *pool, struct xdp_rxq_info *rxq)
>> @@ -212,9 +225,24 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
>> */
>> hlist_add_head(&pool->dev_node, &netdev->xsk_pools);
>>
>> - if (force_copy)
>> + if (force_copy) {
>> /* For copy-mode, we are done. */
>> + err = xp_alloc_heads(pool);
>> + goto out;
>> + }
>> +
>> + if (xsk_pp_supported(netdev)) {
>> + err = xsk_pp_bind(pool, netdev, queue_id);
>> + if (err)
>> + goto err_unreg_pool;
>> +
>> + pool->umem->zc = true;
>> return 0;
>> + }
>> +
>> + err = xp_alloc_heads(pool);
>> + if (err)
>> + goto out;
>>
>> if ((netdev->xdp_features & NETDEV_XDP_ACT_XSK) != NETDEV_XDP_ACT_XSK) {
>> err = -EOPNOTSUPP;
>> @@ -267,8 +295,10 @@ int xp_assign_dev(struct xsk_buff_pool *pool,
>> err_unreg_xsk:
>> xp_disable_drv_zc(pool);
>> err_unreg_pool:
>> - if (!force_zc)
>> - err = 0; /* fallback to copy mode */
>> + /* An old page pool may still own chunks of a failed provider. */
>> + if (!force_zc && !pool->pp)
>> + err = xp_alloc_heads(pool); /* fallback to copy mode */
>> +out:
>> if (err) {
>> pool->umem->flags = umem_flags;
>> xsk_clear_pool_at_qid(netdev, queue_id);
>> @@ -301,7 +331,10 @@ static void __xp_clear_dev(struct xsk_buff_pool *pool)
>> struct net_device *netdev = pool->netdev;
>>
>> netdev_assert_locked_ops_compat(netdev);
>> - xp_disable_drv_zc(pool);
>> + if (pool->pp)
>> + xsk_pp_unbind(pool);
>> + else
>> + xp_disable_drv_zc(pool);
>> xsk_clear_pool_at_qid(netdev, pool->queue_id);
>> hlist_del(&pool->dev_node);
>> pool->netdev = NULL;
>> @@ -474,7 +507,7 @@ static void xp_check_dma_contiguity(struct xsk_dma_map *dma_map)
>>
>> static int xp_init_dma_info(struct xsk_buff_pool *pool, struct xsk_dma_map *dma_map)
>> {
>> - if (!pool->unaligned) {
>> + if (!pool->unaligned && pool->heads) {
>> u32 i;
>>
>> for (i = 0; i < pool->heads_cnt; i++) {
>> diff --git a/net/xdp/xsk_pp.c b/net/xdp/xsk_pp.c
>> index fdd55265a6cd..c2214e718cdb 100644
>> --- a/net/xdp/xsk_pp.c
>> +++ b/net/xdp/xsk_pp.c
>> @@ -8,6 +8,9 @@
>> * +-----RX ring-------+
>> */
>>
>> +#include <net/netdev_lock.h>
>> +#include <net/netdev_queues.h>
>> +#include <net/netdev_rx_queue.h>
>> #include <net/page_pool/helpers.h>
>> #include <net/page_pool/memory_provider.h>
>> #include <net/xdp_sock_drv.h>
>> @@ -15,6 +18,8 @@
>> #include "xsk.h"
>> #include "xsk_queue.h"
>>
>> +#define XSK_PP_DMA_ATTR (DMA_ATTR_WEAK_ORDERING | DMA_ATTR_SKIP_CPU_SYNC)
>> +
>> enum xsk_pp_chunk {
>> XSK_PP_USER, /* owned by userspace */
>> XSK_PP_POOL, /* owned by a page pool */
>> @@ -30,6 +35,8 @@ struct xsk_pp {
>> refcount_t refs;
>> u32 nr_pools;
>> bool dma_need_sync;
>> + /* RX queue of the provider, NULL once it is removed */
>> + struct netdev_rx_queue *rxq;
>> u8 *state;
>> u32 reuse_cnt;
>> u32 reuse[];
>> @@ -236,11 +243,225 @@ static int xsk_pp_nl_fill(void *mp_priv, struct sk_buff *rsp,
>> return 0;
>> }
>>
>> +/* The queue no longer uses the provider, and its DMA stopped */
>> +static void xsk_pp_detach(struct xsk_pp *pp)
>> +{
>> + pp->rxq = NULL;
>> + spin_lock_bh(&pp->lock);
>
> Just curious, but why this protection of the fq here?
After a normal unbind the queue is already stopped, so nothing reads
FILL anyway. It matters when the restart fails and the old queue keeps
running; I have a net fix that keeps the provider on such a queue until
a retry succeeds... but maybe it's better to introduce the lock then.
Let me noodle on it for the next rev.
Björn
next prev parent reply other threads:[~2026-11-11 19:26 UTC|newest]
Thread overview: 26+ 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-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-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-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-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 [this message]
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-10 10:20 ` [PATCH net-next v1 07/11] xsk: Deliver provider chunks without copying 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-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-10 10:20 ` [PATCH net-next v1 11/11] eth: fbnic: Support AF_XDP page pool zero copy 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=875wy3890k.fsf@all.your.base.are.belong.to.us \
--to=bjorn@kernel.org \
--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=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=maciej.fijalkowski@intel.com \
--cc=magnus.karlsson@gmail.com \
--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
all inboxes | Powered by JetHome®