1 // SPDX-License-Identifier: GPL-2.0 2 /* XDP user-space ring structure 3 * Copyright(c) 2018 Intel Corporation. 4 */ 5 6 #include <linux/log2.h> 7 #include <linux/slab.h> 8 #include <linux/overflow.h> 9 #include <linux/vmalloc.h> 10 #include <net/xdp_sock_drv.h> 11 12 #include "xsk_queue.h" 13 14 static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue) 15 { 16 struct xdp_umem_ring *umem_ring; 17 struct xdp_rxtx_ring *rxtx_ring; 18 19 if (umem_queue) 20 return struct_size(umem_ring, desc, q->nentries); 21 return struct_size(rxtx_ring, desc, q->nentries); 22 } 23 24 struct xsk_queue *xskq_create(u32 nentries, bool umem_queue) 25 { 26 struct xsk_queue *q; 27 size_t size; 28 29 q = kzalloc(sizeof(*q), GFP_KERNEL); 30 if (!q) 31 return NULL; 32 33 q->nentries = nentries; 34 q->ring_mask = nentries - 1; 35 36 size = xskq_get_ring_size(q, umem_queue); 37 size = PAGE_ALIGN(size); 38 39 q->ring = vmalloc_user(size); 40 if (!q->ring) { 41 kfree(q); 42 return NULL; 43 } 44 45 q->ring_vmalloc_size = size; 46 return q; 47 } 48 49 void xskq_destroy(struct xsk_queue *q) 50 { 51 if (!q) 52 return; 53 54 vfree(q->ring); 55 kfree(q); 56 } 57