mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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


  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®