mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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…
	
		Reference in a new issue