Skip to content

Commit 035af94

Browse files
isilenceaxboe
authored andcommitted
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 <[email protected]> Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: David Wei <[email protected]> Acked-by: Jakub Kicinski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent cf96310 commit 035af94

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

io_uring/zcrx.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <linux/errno.h>
44
#include <linux/mm.h>
55
#include <linux/io_uring.h>
6+
#include <linux/netdevice.h>
7+
#include <linux/rtnetlink.h>
68

79
#include <uapi/linux/io_uring.h>
810

@@ -128,13 +130,28 @@ static struct io_zcrx_ifq *io_zcrx_ifq_alloc(struct io_ring_ctx *ctx)
128130

129131
ifq->if_rxq = -1;
130132
ifq->ctx = ctx;
133+
spin_lock_init(&ifq->lock);
131134
return ifq;
132135
}
133136

137+
static void io_zcrx_drop_netdev(struct io_zcrx_ifq *ifq)
138+
{
139+
spin_lock(&ifq->lock);
140+
if (ifq->netdev) {
141+
netdev_put(ifq->netdev, &ifq->netdev_tracker);
142+
ifq->netdev = NULL;
143+
}
144+
spin_unlock(&ifq->lock);
145+
}
146+
134147
static void io_zcrx_ifq_free(struct io_zcrx_ifq *ifq)
135148
{
149+
io_zcrx_drop_netdev(ifq);
150+
136151
if (ifq->area)
137152
io_zcrx_free_area(ifq->area);
153+
if (ifq->dev)
154+
put_device(ifq->dev);
138155

139156
io_free_rbuf_ring(ifq);
140157
kfree(ifq);
@@ -195,6 +212,17 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
195212
ifq->rq_entries = reg.rq_entries;
196213
ifq->if_rxq = reg.if_rxq;
197214

215+
ret = -ENODEV;
216+
ifq->netdev = netdev_get_by_index(current->nsproxy->net_ns, reg.if_idx,
217+
&ifq->netdev_tracker, GFP_KERNEL);
218+
if (!ifq->netdev)
219+
goto err;
220+
221+
ifq->dev = ifq->netdev->dev.parent;
222+
if (!ifq->dev)
223+
return -EOPNOTSUPP;
224+
get_device(ifq->dev);
225+
198226
reg.offsets.rqes = sizeof(struct io_uring);
199227
reg.offsets.head = offsetof(struct io_uring, head);
200228
reg.offsets.tail = offsetof(struct io_uring, tail);

io_uring/zcrx.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/io_uring_types.h>
66
#include <net/page_pool/types.h>
7+
#include <net/net_trackers.h>
78

89
struct io_zcrx_area {
910
struct net_iov_area nia;
@@ -27,6 +28,10 @@ struct io_zcrx_ifq {
2728
u32 rq_entries;
2829

2930
u32 if_rxq;
31+
struct device *dev;
32+
struct net_device *netdev;
33+
netdevice_tracker netdev_tracker;
34+
spinlock_t lock;
3035
};
3136

3237
#if defined(CONFIG_IO_URING_ZCRX)

0 commit comments

Comments
 (0)