Message ID | 20250108220644.3528845-15-dw@davidwei.uk (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | io_uring zero copy rx | expand |
On Wed, 8 Jan 2025 14:06:35 -0800 David Wei wrote: > From: Pavel Begunkov <asml.silence@gmail.com> > > Zerocopy receive needs a net device to bind to its rx queue and dma map > buffers. As a preparation to following patches, resolve a net device > from the if_idx parameter with no functional changes otherwise. How do you know if someone unregisters this netdevice? The unregister process waits for all the refs to be released, for *ekhm* historic reasons. Normally ref holders subscribe to netdev events and kill their dependent objects. Perhaps it is somewhere else/later in the series... > +#include <linux/rtnetlink.h> Do you need anything more than rtnl_lock from this header?
On 1/16/25 01:06, Jakub Kicinski wrote: > On Wed, 8 Jan 2025 14:06:35 -0800 David Wei wrote: >> From: Pavel Begunkov <asml.silence@gmail.com> >> >> Zerocopy receive needs a net device to bind to its rx queue and dma map >> buffers. As a preparation to following patches, resolve a net device >> from the if_idx parameter with no functional changes otherwise. > > How do you know if someone unregisters this netdevice? > The unregister process waits for all the refs to be released, > for *ekhm* historic reasons. Normally ref holders subscribe > to netdev events and kill their dependent objects. Perhaps > it is somewhere else/later in the series... Ok, I can pin the struct device long term instead and kill netdev in the uninstall callback off unregister_netdevice_many_notify(), if that works with you. >> +#include <linux/rtnetlink.h> > > Do you need anything more than rtnl_lock from this header? No, I don't believe so
On Thu, 16 Jan 2025 02:33:06 +0000 Pavel Begunkov wrote: > On 1/16/25 01:06, Jakub Kicinski wrote: > > On Wed, 8 Jan 2025 14:06:35 -0800 David Wei wrote: > >> From: Pavel Begunkov <asml.silence@gmail.com> > >> > >> Zerocopy receive needs a net device to bind to its rx queue and dma map > >> buffers. As a preparation to following patches, resolve a net device > >> from the if_idx parameter with no functional changes otherwise. > > > > How do you know if someone unregisters this netdevice? > > The unregister process waits for all the refs to be released, > > for *ekhm* historic reasons. Normally ref holders subscribe > > to netdev events and kill their dependent objects. Perhaps > > it is somewhere else/later in the series... > > Ok, I can pin the struct device long term instead and kill > netdev in the uninstall callback off > unregister_netdevice_many_notify(), if that works with you. I think that would work. You mean the "underlying" device, right, netdev->dev.parent ? Like page_pool itself does. SG.
On 1/16/25 03:12, Jakub Kicinski wrote: > On Thu, 16 Jan 2025 02:33:06 +0000 Pavel Begunkov wrote: >> On 1/16/25 01:06, Jakub Kicinski wrote: >>> On Wed, 8 Jan 2025 14:06:35 -0800 David Wei wrote: >>>> From: Pavel Begunkov <asml.silence@gmail.com> >>>> >>>> Zerocopy receive needs a net device to bind to its rx queue and dma map >>>> buffers. As a preparation to following patches, resolve a net device >>>> from the if_idx parameter with no functional changes otherwise. >>> >>> How do you know if someone unregisters this netdevice? >>> The unregister process waits for all the refs to be released, >>> for *ekhm* historic reasons. Normally ref holders subscribe >>> to netdev events and kill their dependent objects. Perhaps >>> it is somewhere else/later in the series... >> >> Ok, I can pin the struct device long term instead and kill >> netdev in the uninstall callback off >> unregister_netdevice_many_notify(), if that works with you. > > I think that would work. You mean the "underlying" device, right, > netdev->dev.parent ? Like page_pool itself does. SG. Right, that one
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index 04883a3ae80c..e6cca6747148 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -3,6 +3,8 @@ #include <linux/errno.h> #include <linux/mm.h> #include <linux/io_uring.h> +#include <linux/netdevice.h> +#include <linux/rtnetlink.h> #include <uapi/linux/io_uring.h> @@ -136,6 +138,8 @@ static void io_zcrx_ifq_free(struct io_zcrx_ifq *ifq) if (ifq->area) io_zcrx_free_area(ifq->area); + if (ifq->dev) + netdev_put(ifq->dev, &ifq->netdev_tracker); io_free_rbuf_ring(ifq); kfree(ifq); } @@ -195,6 +199,12 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx, ifq->rq_entries = reg.rq_entries; ifq->if_rxq = reg.if_rxq; + ret = -ENODEV; + ifq->dev = netdev_get_by_index(current->nsproxy->net_ns, reg.if_idx, + &ifq->netdev_tracker, GFP_KERNEL); + if (!ifq->dev) + goto err; + reg.offsets.rqes = sizeof(struct io_uring); reg.offsets.head = offsetof(struct io_uring, head); reg.offsets.tail = offsetof(struct io_uring, tail); diff --git a/io_uring/zcrx.h b/io_uring/zcrx.h index 53fd94b65b38..46988a1dbd54 100644 --- a/io_uring/zcrx.h +++ b/io_uring/zcrx.h @@ -4,6 +4,7 @@ #include <linux/io_uring_types.h> #include <net/page_pool/types.h> +#include <net/net_trackers.h> struct io_zcrx_area { struct net_iov_area nia; @@ -27,6 +28,8 @@ struct io_zcrx_ifq { u32 rq_entries; u32 if_rxq; + struct net_device *dev; + netdevice_tracker netdev_tracker; }; #if defined(CONFIG_IO_URING_ZCRX)