1 // SPDX-License-Identifier: GPL-2.0
2 /* XDP user-space ring structure
3 * Copyright(c) 2018 Intel Corporation.
6 #include <linux/log2.h>
7 #include <linux/slab.h>
8 #include <linux/overflow.h>
10 #include "xsk_queue.h"
12 void xskq_set_umem(struct xsk_queue
*q
, u64 size
, u64 chunk_mask
)
18 q
->chunk_mask
= chunk_mask
;
21 static size_t xskq_get_ring_size(struct xsk_queue
*q
, bool umem_queue
)
23 struct xdp_umem_ring
*umem_ring
;
24 struct xdp_rxtx_ring
*rxtx_ring
;
27 return struct_size(umem_ring
, desc
, q
->nentries
);
28 return struct_size(rxtx_ring
, desc
, q
->nentries
);
31 struct xsk_queue
*xskq_create(u32 nentries
, bool umem_queue
)
37 q
= kzalloc(sizeof(*q
), GFP_KERNEL
);
41 q
->nentries
= nentries
;
42 q
->ring_mask
= nentries
- 1;
44 gfp_flags
= GFP_KERNEL
| __GFP_ZERO
| __GFP_NOWARN
|
45 __GFP_COMP
| __GFP_NORETRY
;
46 size
= xskq_get_ring_size(q
, umem_queue
);
48 q
->ring
= (struct xdp_ring
*)__get_free_pages(gfp_flags
,
58 void xskq_destroy(struct xsk_queue
*q
)
63 page_frag_free(q
->ring
);
67 struct xdp_umem_fq_reuse
*xsk_reuseq_prepare(u32 nentries
)
69 struct xdp_umem_fq_reuse
*newq
;
71 /* Check for overflow */
72 if (nentries
> (u32
)roundup_pow_of_two(nentries
))
74 nentries
= roundup_pow_of_two(nentries
);
76 newq
= kvmalloc(struct_size(newq
, handles
, nentries
), GFP_KERNEL
);
79 memset(newq
, 0, offsetof(typeof(*newq
), handles
));
81 newq
->nentries
= nentries
;
84 EXPORT_SYMBOL_GPL(xsk_reuseq_prepare
);
86 struct xdp_umem_fq_reuse
*xsk_reuseq_swap(struct xdp_umem
*umem
,
87 struct xdp_umem_fq_reuse
*newq
)
89 struct xdp_umem_fq_reuse
*oldq
= umem
->fq_reuse
;
92 umem
->fq_reuse
= newq
;
96 if (newq
->nentries
< oldq
->length
)
99 memcpy(newq
->handles
, oldq
->handles
,
100 array_size(oldq
->length
, sizeof(u64
)));
101 newq
->length
= oldq
->length
;
103 umem
->fq_reuse
= newq
;
106 EXPORT_SYMBOL_GPL(xsk_reuseq_swap
);
108 void xsk_reuseq_free(struct xdp_umem_fq_reuse
*rq
)
112 EXPORT_SYMBOL_GPL(xsk_reuseq_free
);
114 void xsk_reuseq_destroy(struct xdp_umem
*umem
)
116 xsk_reuseq_free(umem
->fq_reuse
);
117 umem
->fq_reuse
= NULL
;