io_uring/zcrx: grab a net device
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@kernel.dk> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: David Wei <dw@davidwei.uk> Acked-by: Jakub Kicinski <kuba@kernel.org> Link: https://lore.kernel.org/r/20250215000947.789731-4-dw@davidwei.uk Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
cf96310c5f
commit
035af94b39
2 changed files with 33 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue