[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