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> |
a71506a4 | 9 | #include <net/xdp_sock_drv.h> |
423f3832 MK |
10 | |
11 | #include "xsk_queue.h" | |
12 | ||
1d9cb1f3 | 13 | static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue) |
423f3832 | 14 | { |
1d9cb1f3 MK |
15 | struct xdp_umem_ring *umem_ring; |
16 | struct xdp_rxtx_ring *rxtx_ring; | |
423f3832 | 17 | |
1d9cb1f3 MK |
18 | if (umem_queue) |
19 | return struct_size(umem_ring, desc, q->nentries); | |
20 | return struct_size(rxtx_ring, desc, q->nentries); | |
b9b6b68e BT |
21 | } |
22 | ||
23 | struct xsk_queue *xskq_create(u32 nentries, bool umem_queue) | |
423f3832 MK |
24 | { |
25 | struct xsk_queue *q; | |
26 | gfp_t gfp_flags; | |
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 | gfp_flags = GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN | | |
37 | __GFP_COMP | __GFP_NORETRY; | |
1d9cb1f3 | 38 | size = xskq_get_ring_size(q, umem_queue); |
423f3832 MK |
39 | |
40 | q->ring = (struct xdp_ring *)__get_free_pages(gfp_flags, | |
41 | get_order(size)); | |
42 | if (!q->ring) { | |
43 | kfree(q); | |
44 | return NULL; | |
45 | } | |
46 | ||
47 | return q; | |
48 | } | |
49 | ||
50 | void xskq_destroy(struct xsk_queue *q) | |
51 | { | |
52 | if (!q) | |
53 | return; | |
54 | ||
55 | page_frag_free(q->ring); | |
56 | kfree(q); | |
57 | } |