On 6/13/24 02:35, Mina Almasry wrote:
Add netdev_rx_queue_restart() function to netdev_rx_queue.h
see nit below
Reviewed-by: Pavel Begunkov asml.silence@gmail.com
Signed-off-by: David Wei dw@davidwei.uk Signed-off-by: Mina Almasry almasrymina@google.com
v11:
- Fix not checking dev->queue_mgmt_ops (Pavel).
- Fix ndo_queue_mem_free call that passed the wrong pointer (David).
v9: https://lore.kernel.org/all/20240502045410.3524155-4-dw@davidwei.uk/ (submitted by David).
- fixed SPDX license identifier (Simon).
- Rebased on top of merged queue API definition, and changed implementation to match that.
- Replace rtnl_lock() with rtnl_is_locked() to make it useable from my netlink code where rtnl is already locked.
include/net/netdev_rx_queue.h | 3 ++ net/core/Makefile | 1 + net/core/netdev_rx_queue.c | 74 +++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 net/core/netdev_rx_queue.c
diff --git a/include/net/netdev_rx_queue.h b/include/net/netdev_rx_queue.h index aa1716fb0e53c..e78ca52d67fbf 100644 --- a/include/net/netdev_rx_queue.h +++ b/include/net/netdev_rx_queue.h @@ -54,4 +54,7 @@ get_netdev_rx_queue_index(struct netdev_rx_queue *queue) return index; } #endif
+int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq);
- #endif
diff --git a/net/core/Makefile b/net/core/Makefile index 62be9aef25285..f82232b358a2c 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o obj-y += net-sysfs.o obj-y += hotdata.o +obj-y += netdev_rx_queue.o obj-$(CONFIG_PAGE_POOL) += page_pool.o page_pool_user.o obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o diff --git a/net/core/netdev_rx_queue.c b/net/core/netdev_rx_queue.c new file mode 100644 index 0000000000000..de0575cf6df5d --- /dev/null +++ b/net/core/netdev_rx_queue.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/netdevice.h> +#include <net/netdev_queues.h> +#include <net/netdev_rx_queue.h>
+int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx) +{
- void *new_mem, *old_mem;
- int err;
- if (!dev->queue_mgmt_ops || !dev->queue_mgmt_ops->ndo_queue_stop ||
!dev->queue_mgmt_ops->ndo_queue_mem_free ||
!dev->queue_mgmt_ops->ndo_queue_mem_alloc ||
!dev->queue_mgmt_ops->ndo_queue_start)
return -EOPNOTSUPP;
- DEBUG_NET_WARN_ON_ONCE(!rtnl_is_locked());
- new_mem = kvzalloc(dev->queue_mgmt_ops->ndo_queue_mem_size, GFP_KERNEL);
- if (!new_mem)
return -ENOMEM;
- old_mem = kvzalloc(dev->queue_mgmt_ops->ndo_queue_mem_size, GFP_KERNEL);
- if (!old_mem) {
err = -ENOMEM;
goto err_free_new_mem;
- }
- err = dev->queue_mgmt_ops->ndo_queue_mem_alloc(dev, new_mem, rxq_idx);
- if (err)
goto err_free_old_mem;
- err = dev->queue_mgmt_ops->ndo_queue_stop(dev, old_mem, rxq_idx);
- if (err)
goto err_free_new_queue_mem;
- err = dev->queue_mgmt_ops->ndo_queue_start(dev, new_mem, rxq_idx);
- if (err)
goto err_start_queue;
- dev->queue_mgmt_ops->ndo_queue_mem_free(dev, old_mem);
- kvfree(old_mem);
- kvfree(new_mem);
- return 0;
+err_start_queue:
- /* 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.
*
* WARN if the we fail to recover the old rx queue, and at least free
nit "if the we"
* old_mem so we don't also leak that.
*/
- if (dev->queue_mgmt_ops->ndo_queue_start(dev, old_mem, rxq_idx)) {
WARN(1,
"Failed to restart old queue in error path. RX queue %d may be unhealthy.",
rxq_idx);
dev->queue_mgmt_ops->ndo_queue_mem_free(dev, old_mem);
- }
+err_free_new_queue_mem:
- dev->queue_mgmt_ops->ndo_queue_mem_free(dev, new_mem);
+err_free_old_mem:
- kvfree(old_mem);
+err_free_new_mem:
- kvfree(new_mem);
- return err;
+}