mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 06:53:04 +00:00
netdev: add netdev_rx_queue_restart()
Add netdev_rx_queue_restart(), which resets an rx queue using the queue API recently merged[1]. The queue API was merged to enable the core net stack to reset individual rx queues to actuate changes in the rx queue's configuration. In later patches in this series, we will use netdev_rx_queue_restart() to reset rx queues after binding or unbinding dmabuf configuration, which will cause reallocation of the page_pool to repopulate its memory using the new configuration. [1] https://lore.kernel.org/netdev/20240430231420.699177-1-shailend@google.com/T/ Signed-off-by: David Wei <dw@davidwei.uk> Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20240910171458.219195-2-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
24b8c19314
commit
7c88f86576
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
74
net/core/netdev_rx_queue.c
Normal file
74
net/core/netdev_rx_queue.c
Normal file
|
@ -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;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
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 we fail to recover the old rx queue, and at least free
|
||||
* 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user