From: Stanislav Fomichev <sdf.kernel@gmail.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, hawk@kernel.org,
ilias.apalodimas@linaro.org, sdf@fomichev.me,
bobbyeshleman@meta.com, almasrymina@google.com,
kaiyuanz@google.com, linux-kernel@vger.kernel.org
Subject: [PATCH net-next v2 1/3] net: netmem: move to index based freelist
Date: Fri, 25 Sep 2026 13:15:20 -0700 [thread overview]
Message-ID: <20260925201522.254717-2-sdf@fomichev.me> (raw)
In-Reply-To: <20260925201522.254717-1-sdf@fomichev.me>
Move devmem's freelist to an index-based approach similar to io_uring.
This halves the memory requirements for the freelist.
Reviewed-by: Mina Almasry <almasrymina@google.com>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
net/core/devmem.c | 50 ++++++++++++++++++++++++++++++++++++-----------
net/core/devmem.h | 4 ++--
2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/net/core/devmem.c b/net/core/devmem.c
index a9d86b5a5588..704d02bd8bc8 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -29,6 +29,29 @@ static DEFINE_XARRAY_FLAGS(net_devmem_dmabuf_bindings, XA_FLAGS_ALLOC1);
static const struct memory_provider_ops dmabuf_devmem_ops;
+static struct net_iov *net_iov_free_pop(struct net_iov_area *area,
+ u32 *freelist, u32 *free_count)
+{
+ u32 idx;
+
+ if (unlikely(!*free_count))
+ return NULL;
+
+ idx = freelist[--(*free_count)];
+ return &area->niovs[idx];
+}
+
+static void net_iov_free_push(struct net_iov_area *area,
+ u32 *freelist, u32 *free_count,
+ struct net_iov *niov)
+{
+ if (WARN_ON_ONCE(net_iov_owner(niov) != area ||
+ *free_count >= area->num_niovs))
+ return;
+
+ freelist[(*free_count)++] = net_iov_idx(niov);
+}
+
static void net_devmem_dmabuf_binding_release(struct percpu_ref *ref)
{
struct net_devmem_dmabuf_binding *binding =
@@ -44,7 +67,7 @@ void __net_devmem_dmabuf_binding_free(struct work_struct *wq)
if (binding->freelist)
WARN(binding->free_count != binding->area.num_niovs,
- "destroying dmabuf binding with outstanding net_iovs: total=%zu, free=%zu",
+ "destroying dmabuf binding with outstanding net_iovs: total=%zu, free=%u",
binding->area.num_niovs, binding->free_count);
kvfree(binding->area.niovs);
@@ -63,14 +86,15 @@ static unsigned int
net_devmem_alloc_dmabuf_bulk(struct net_devmem_dmabuf_binding *binding,
netmem_ref *netmems, unsigned int count)
{
+ struct net_iov *niov;
unsigned int i;
spin_lock_bh(&binding->freelist_lock);
- count = min_t(size_t, count, binding->free_count);
+ count = min(count, binding->free_count);
for (i = 0; i < count; i++) {
- struct net_iov *niov = binding->freelist[--binding->free_count];
-
+ niov = net_iov_free_pop(&binding->area, binding->freelist,
+ &binding->free_count);
netmems[i] = net_iov_to_netmem(niov);
}
@@ -84,12 +108,8 @@ void net_devmem_free_dmabuf(struct net_iov *niov)
struct net_devmem_dmabuf_binding *binding = net_devmem_iov_binding(niov);
spin_lock_bh(&binding->freelist_lock);
- if (WARN_ON_ONCE(binding->free_count >= binding->area.num_niovs)) {
- spin_unlock_bh(&binding->freelist_lock);
- return;
- }
-
- binding->freelist[binding->free_count++] = niov;
+ net_iov_free_push(&binding->area, binding->freelist,
+ &binding->free_count, niov);
spin_unlock_bh(&binding->freelist_lock);
}
@@ -228,6 +248,12 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
goto err_unmap;
}
+ if ((dmabuf->size >> niov_shift) > U32_MAX) {
+ err = -E2BIG;
+ NL_SET_ERR_MSG(extack, "dmabuf contains too many net_iovs");
+ goto err_unmap;
+ }
+
binding->area.base_virtual = 0;
binding->area.num_niovs = dmabuf->size >> niov_shift;
if (direction == DMA_TO_DEVICE) {
@@ -279,7 +305,9 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
if (direction == DMA_TO_DEVICE)
binding->tx_vec[niov_idx] = niov;
else
- binding->freelist[binding->free_count++] = niov;
+ net_iov_free_push(&binding->area,
+ binding->freelist,
+ &binding->free_count, niov);
dma_addr += niov_size;
}
}
diff --git a/net/core/devmem.h b/net/core/devmem.h
index f71d9a2bcb3d..28d6fa7bcb57 100644
--- a/net/core/devmem.h
+++ b/net/core/devmem.h
@@ -58,8 +58,8 @@ struct net_devmem_dmabuf_binding {
struct xarray bound_rxqs;
spinlock_t freelist_lock ____cacheline_aligned_in_smp;
- size_t free_count;
- struct net_iov **freelist;
+ u32 free_count;
+ u32 *freelist;
/* ID of this binding. Globally unique to all bindings currently
* active.
--
2.53.0-Meta
next prev parent reply other threads:[~2026-09-25 20:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-25 20:15 [PATCH net-next v2 0/3] net: consolidate devmem net_iov freelist and DMA handling Stanislav Fomichev
2026-09-25 20:15 ` Stanislav Fomichev [this message]
2026-09-25 20:15 ` [PATCH net-next v2 2/3] net: devmem: use memory provider helpers for net_iovs Stanislav Fomichev
2026-09-25 20:15 ` [PATCH net-next v2 3/3] net: devmem: decode DMA addresses for TX Stanislav Fomichev
2026-09-29 9:43 ` Paolo Abeni
2026-09-29 13:39 ` Paolo Abeni
2026-09-29 15:55 ` Stanislav Fomichev
2026-09-29 14:10 ` [PATCH net-next v2 0/3] net: consolidate devmem net_iov freelist and DMA handling patchwork-bot+netdevbpf
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=20260925201522.254717-2-sdf@fomichev.me \
--to=sdf.kernel@gmail.com \
--cc=almasrymina@google.com \
--cc=bobbyeshleman@meta.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=ilias.apalodimas@linaro.org \
--cc=kaiyuanz@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
/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®