From: Pavel Begunkov <asml.silence@xxxxxxxxx> 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. Reviewed-by: Jens Axboe <axboe@xxxxxxxxx> Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> Signed-off-by: David Wei <dw@xxxxxxxxxxx> --- io_uring/zcrx.c | 28 ++++++++++++++++++++++++++++ io_uring/zcrx.h | 5 +++++ 2 files changed, 33 insertions(+) diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index 04883a3ae80c..435cd634f91c 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> @@ -128,13 +130,28 @@ static struct io_zcrx_ifq *io_zcrx_ifq_alloc(struct io_ring_ctx *ctx) ifq->if_rxq = -1; ifq->ctx = ctx; + spin_lock_init(&ifq->lock); return ifq; } +static void io_zcrx_drop_netdev(struct io_zcrx_ifq *ifq) +{ + spin_lock(&ifq->lock); + if (ifq->netdev) { + netdev_put(ifq->netdev, &ifq->netdev_tracker); + ifq->netdev = NULL; + } + spin_unlock(&ifq->lock); +} + static void io_zcrx_ifq_free(struct io_zcrx_ifq *ifq) { + io_zcrx_drop_netdev(ifq); + if (ifq->area) io_zcrx_free_area(ifq->area); + if (ifq->dev) + put_device(ifq->dev); io_free_rbuf_ring(ifq); kfree(ifq); @@ -195,6 +212,17 @@ 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->netdev = netdev_get_by_index(current->nsproxy->net_ns, reg.if_idx, + &ifq->netdev_tracker, GFP_KERNEL); + if (!ifq->netdev) + goto err; + + ifq->dev = ifq->netdev->dev.parent; + if (!ifq->dev) + return -EOPNOTSUPP; + get_device(ifq->dev); + 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..595bca0001d2 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,10 @@ struct io_zcrx_ifq { u32 rq_entries; u32 if_rxq; + struct device *dev; + struct net_device *netdev; + netdevice_tracker netdev_tracker; + spinlock_t lock; }; #if defined(CONFIG_IO_URING_ZCRX) -- 2.43.5