Thread (66 messages) 66 messages, 5 authors, 2025-08-06

[RFC v1 21/22] net: parametrise mp open with a queue config

From: Pavel Begunkov <asml.silence@gmail.com>
Date: 2025-07-28 11:03:45
Also in: io-uring
Subsystem: io_uring, io_uring zcrx, networking [general], page pool, the rest · Maintainers: Jens Axboe, Pavel Begunkov, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jesper Dangaard Brouer, Ilias Apalodimas, Linus Torvalds

This patch allows memory providers to pass a queue config when opening a
queue. It'll be used in the next patch to pass a custom rx buffer length
from zcrx. As there are many users of netdev_rx_queue_restart(), it's
allowed to pass a NULL qcfg, in which case the function will use the
default configuration.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 include/net/page_pool/memory_provider.h |  4 +-
 io_uring/zcrx.c                         |  2 +-
 net/core/netdev_rx_queue.c              | 50 +++++++++++++++++--------
 3 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/include/net/page_pool/memory_provider.h b/include/net/page_pool/memory_provider.h
index ada4f968960a..c08ba208f67d 100644
--- a/include/net/page_pool/memory_provider.h
+++ b/include/net/page_pool/memory_provider.h
@@ -5,6 +5,7 @@
 #include <net/netmem.h>
 #include <net/page_pool/types.h>
 
+struct netdev_queue_config;
 struct netdev_rx_queue;
 struct netlink_ext_ack;
 struct sk_buff;
@@ -24,7 +25,8 @@ void net_mp_niov_set_page_pool(struct page_pool *pool, struct net_iov *niov);
 void net_mp_niov_clear_page_pool(struct net_iov *niov);
 
 int net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
-		    struct pp_memory_provider_params *p);
+		    struct pp_memory_provider_params *p,
+		    struct netdev_queue_config *qcfg);
 int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
 		      const struct pp_memory_provider_params *p,
 		      struct netlink_ext_ack *extack);
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index 985c7386e24b..a00243e10164 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -595,7 +595,7 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
 
 	mp_param.mp_ops = &io_uring_pp_zc_ops;
 	mp_param.mp_priv = ifq;
-	ret = net_mp_open_rxq(ifq->netdev, reg.if_rxq, &mp_param);
+	ret = net_mp_open_rxq(ifq->netdev, reg.if_rxq, &mp_param, NULL);
 	if (ret)
 		goto err;
 	ifq->if_rxq = reg.if_rxq;
diff --git a/net/core/netdev_rx_queue.c b/net/core/netdev_rx_queue.c
index 7c691eb1a48b..0dbfdb5f5b91 100644
--- a/net/core/netdev_rx_queue.c
+++ b/net/core/netdev_rx_queue.c
@@ -10,12 +10,14 @@
 #include "dev.h"
 #include "page_pool_priv.h"
 
-int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
-			    struct netlink_ext_ack *extack)
+static int netdev_rx_queue_restart_cfg(struct net_device *dev,
+				unsigned int rxq_idx,
+				struct netlink_ext_ack *extack,
+				struct netdev_queue_config *qcfg)
 {
 	struct netdev_rx_queue *rxq = __netif_get_rx_queue(dev, rxq_idx);
 	const struct netdev_queue_mgmt_ops *qops = dev->queue_mgmt_ops;
-	struct netdev_queue_config qcfg;
+	struct netdev_queue_config tmp_qcfg;
 	void *new_mem, *old_mem;
 	int err;
 
@@ -35,15 +37,18 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
 		goto err_free_new_mem;
 	}
 
-	netdev_queue_config(dev, rxq_idx, &qcfg);
+	if (!qcfg) {
+		qcfg = &tmp_qcfg;
+		netdev_queue_config(dev, rxq_idx, qcfg);
+	}
 
 	if (qops->ndo_queue_cfg_validate) {
-		err = qops->ndo_queue_cfg_validate(dev, rxq_idx, &qcfg, extack);
+		err = qops->ndo_queue_cfg_validate(dev, rxq_idx, qcfg, extack);
 		if (err)
 			goto err_free_old_mem;
 	}
 
-	err = qops->ndo_queue_mem_alloc(dev, &qcfg, new_mem, rxq_idx);
+	err = qops->ndo_queue_mem_alloc(dev, qcfg, new_mem, rxq_idx);
 	if (err)
 		goto err_free_old_mem;
 
@@ -56,7 +61,7 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
 		if (err)
 			goto err_free_new_queue_mem;
 
-		err = qops->ndo_queue_start(dev, &qcfg, new_mem, rxq_idx);
+		err = qops->ndo_queue_start(dev, qcfg, new_mem, rxq_idx);
 		if (err)
 			goto err_start_queue;
 	} else {
@@ -71,7 +76,7 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
 	return 0;
 
 err_start_queue:
-	__netdev_queue_config(dev, rxq_idx, &qcfg, false);
+	__netdev_queue_config(dev, rxq_idx, qcfg, false);
 	/* Restarting the queue with old_mem should be successful as we haven't
 	 * changed any of the queue configuration, and there is not much we can
 	 * do to recover from a failure here.
@@ -79,7 +84,7 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
 	 * WARN if we fail to recover the old rx queue, and at least free
 	 * old_mem so we don't also leak that.
 	 */
-	if (qops->ndo_queue_start(dev, &qcfg, old_mem, rxq_idx)) {
+	if (qops->ndo_queue_start(dev, qcfg, old_mem, rxq_idx)) {
 		WARN(1,
 		     "Failed to restart old queue in error path. RX queue %d may be unhealthy.",
 		     rxq_idx);
@@ -97,11 +102,18 @@ int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
 
 	return err;
 }
+
+int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx,
+			    struct netlink_ext_ack *extack)
+{
+	return netdev_rx_queue_restart_cfg(dev, rxq_idx, extack, NULL);
+}
 EXPORT_SYMBOL_NS_GPL(netdev_rx_queue_restart, "NETDEV_INTERNAL");
 
-int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
-		      const struct pp_memory_provider_params *p,
-		      struct netlink_ext_ack *extack)
+static int __net_mp_open_rxq_cfg(struct net_device *dev, unsigned int rxq_idx,
+				const struct pp_memory_provider_params *p,
+				struct netlink_ext_ack *extack,
+				struct netdev_queue_config *qcfg)
 {
 	struct netdev_rx_queue *rxq;
 	int ret;
@@ -143,7 +155,7 @@ int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
 #endif
 
 	rxq->mp_params = *p;
-	ret = netdev_rx_queue_restart(dev, rxq_idx, extack);
+	ret = netdev_rx_queue_restart_cfg(dev, rxq_idx, extack, qcfg);
 	if (ret) {
 		rxq->mp_params.mp_ops = NULL;
 		rxq->mp_params.mp_priv = NULL;
@@ -151,13 +163,21 @@ int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
 	return ret;
 }
 
+int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
+		      const struct pp_memory_provider_params *p,
+		      struct netlink_ext_ack *extack)
+{
+	return __net_mp_open_rxq_cfg(dev, rxq_idx, p, extack, NULL);
+}
+
 int net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
-		    struct pp_memory_provider_params *p)
+		    struct pp_memory_provider_params *p,
+		    struct netdev_queue_config *qcfg)
 {
 	int ret;
 
 	netdev_lock(dev);
-	ret = __net_mp_open_rxq(dev, rxq_idx, p, NULL);
+	ret = __net_mp_open_rxq_cfg(dev, rxq_idx, p, NULL, qcfg);
 	netdev_unlock(dev);
 	return ret;
 }
-- 
2.49.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help