Commit f8350a43 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jakub Kicinski
Browse files

net: page_pool: add a mp hook to unregister_netdevice*



Devmem TCP needs a hook in unregister_netdevice_many_notify() to upkeep
the set tracking queues it's bound to, i.e. ->bound_rxqs. Instead of
devmem sticking directly out of the genetic path, add a mp function.

Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarMina Almasry <almasrymina@google.com>
Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: default avatarDavid Wei <dw@davidwei.uk>
Link: https://patch.msgid.link/20250204215622.695511-8-dw@davidwei.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2508a46f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ struct memory_provider_ops {
	void (*destroy)(struct page_pool *pool);
	int (*nl_fill)(void *mp_priv, struct sk_buff *rsp,
		       struct netdev_rx_queue *rxq);
	void (*uninstall)(void *mp_priv, struct netdev_rx_queue *rxq);
};

#endif
+15 −1
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@
#include <net/netdev_rx_queue.h>
#include <net/page_pool/types.h>
#include <net/page_pool/helpers.h>
#include <net/page_pool/memory_provider.h>
#include <net/rps.h>
#include <linux/phy_link_topology.h>

@@ -11724,6 +11725,19 @@ void unregister_netdevice_queue(struct net_device *dev, struct list_head *head)
}
EXPORT_SYMBOL(unregister_netdevice_queue);

static void dev_memory_provider_uninstall(struct net_device *dev)
{
	unsigned int i;

	for (i = 0; i < dev->real_num_rx_queues; i++) {
		struct netdev_rx_queue *rxq = &dev->_rx[i];
		struct pp_memory_provider_params *p = &rxq->mp_params;

		if (p->mp_ops && p->mp_ops->uninstall)
			p->mp_ops->uninstall(rxq->mp_params.mp_priv, rxq);
	}
}

void unregister_netdevice_many_notify(struct list_head *head,
				      u32 portid, const struct nlmsghdr *nlh)
{
@@ -11778,7 +11792,7 @@ void unregister_netdevice_many_notify(struct list_head *head,
		dev_tcx_uninstall(dev);
		dev_xdp_uninstall(dev);
		bpf_dev_bound_netdev_unregister(dev);
		dev_dmabuf_uninstall(dev);
		dev_memory_provider_uninstall(dev);

		netdev_offload_xstats_disable_all(dev);

+16 −20
Original line number Diff line number Diff line
@@ -320,26 +320,6 @@ net_devmem_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
	return ERR_PTR(err);
}

void dev_dmabuf_uninstall(struct net_device *dev)
{
	struct net_devmem_dmabuf_binding *binding;
	struct netdev_rx_queue *rxq;
	unsigned long xa_idx;
	unsigned int i;

	for (i = 0; i < dev->real_num_rx_queues; i++) {
		binding = dev->_rx[i].mp_params.mp_priv;
		if (!binding)
			continue;

		xa_for_each(&binding->bound_rxqs, xa_idx, rxq)
			if (rxq == &dev->_rx[i]) {
				xa_erase(&binding->bound_rxqs, xa_idx);
				break;
			}
	}
}

/*** "Dmabuf devmem memory provider" ***/

int mp_dmabuf_devmem_init(struct page_pool *pool)
@@ -415,10 +395,26 @@ static int mp_dmabuf_devmem_nl_fill(void *mp_priv, struct sk_buff *rsp,
	return nla_put_u32(rsp, type, binding->id);
}

static void mp_dmabuf_devmem_uninstall(void *mp_priv,
				       struct netdev_rx_queue *rxq)
{
	struct net_devmem_dmabuf_binding *binding = mp_priv;
	struct netdev_rx_queue *bound_rxq;
	unsigned long xa_idx;

	xa_for_each(&binding->bound_rxqs, xa_idx, bound_rxq) {
		if (bound_rxq == rxq) {
			xa_erase(&binding->bound_rxqs, xa_idx);
			break;
		}
	}
}

static const struct memory_provider_ops dmabuf_devmem_ops = {
	.init			= mp_dmabuf_devmem_init,
	.destroy		= mp_dmabuf_devmem_destroy,
	.alloc_netmems		= mp_dmabuf_devmem_alloc_netmems,
	.release_netmem		= mp_dmabuf_devmem_release_page,
	.nl_fill		= mp_dmabuf_devmem_nl_fill,
	.uninstall		= mp_dmabuf_devmem_uninstall,
};
+0 −5
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding);
int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
				    struct net_devmem_dmabuf_binding *binding,
				    struct netlink_ext_ack *extack);
void dev_dmabuf_uninstall(struct net_device *dev);

static inline struct dmabuf_genpool_chunk_owner *
net_devmem_iov_to_chunk_owner(const struct net_iov *niov)
@@ -145,10 +144,6 @@ net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
	return -EOPNOTSUPP;
}

static inline void dev_dmabuf_uninstall(struct net_device *dev)
{
}

static inline struct net_iov *
net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
{