Commit | Line | Data |
---|---|---|
423f3832 MK |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* XDP user-space ring structure | |
3 | * Copyright(c) 2018 Intel Corporation. | |
423f3832 MK |
4 | */ |
5 | ||
f5bd9138 | 6 | #include <linux/log2.h> |
423f3832 | 7 | #include <linux/slab.h> |
f5bd9138 | 8 | #include <linux/overflow.h> |
9f78bf33 | 9 | #include <linux/vmalloc.h> |
a71506a4 | 10 | #include <net/xdp_sock_drv.h> |
423f3832 MK |
11 | |
12 | #include "xsk_queue.h" | |
13 | ||
1d9cb1f3 | 14 | static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue) |
423f3832 | 15 | { |
1d9cb1f3 MK |
16 | struct xdp_umem_ring *umem_ring; |
17 | struct xdp_rxtx_ring *rxtx_ring; | |
423f3832 | 18 | |
1d9cb1f3 MK |
19 | if (umem_queue) |
20 | return struct_size(umem_ring, desc, q->nentries); | |
21 | return struct_size(rxtx_ring, desc, q->nentries); | |
b9b6b68e BT |
22 | } |
23 | ||
24 | struct xsk_queue *xskq_create(u32 nentries, bool umem_queue) | |
423f3832 MK |
25 | { |
26 | struct xsk_queue *q; | |
423f3832 MK |
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 | ||
1d9cb1f3 | 36 | size = xskq_get_ring_size(q, umem_queue); |
a12bbb3c AK |
37 | |
38 | /* size which is overflowing or close to SIZE_MAX will become 0 in | |
39 | * PAGE_ALIGN(), checking SIZE_MAX is enough due to the previous | |
40 | * is_power_of_2(), the rest will be handled by vmalloc_user() | |
41 | */ | |
42 | if (unlikely(size == SIZE_MAX)) { | |
43 | kfree(q); | |
44 | return NULL; | |
45 | } | |
46 | ||
9f78bf33 | 47 | size = PAGE_ALIGN(size); |
423f3832 | 48 | |
9f78bf33 | 49 | q->ring = vmalloc_user(size); |
423f3832 MK |
50 | if (!q->ring) { |
51 | kfree(q); | |
52 | return NULL; | |
53 | } | |
54 | ||
9f78bf33 | 55 | q->ring_vmalloc_size = size; |
423f3832 MK |
56 | return q; |
57 | } | |
58 | ||
59 | void xskq_destroy(struct xsk_queue *q) | |
60 | { | |
61 | if (!q) | |
62 | return; | |
63 | ||
9f78bf33 | 64 | vfree(q->ring); |
423f3832 MK |
65 | kfree(q); |
66 | } |