0001
0002
0003
0004
0005
0006 #include <linux/log2.h>
0007 #include <linux/slab.h>
0008 #include <linux/overflow.h>
0009 #include <net/xdp_sock_drv.h>
0010
0011 #include "xsk_queue.h"
0012
0013 static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue)
0014 {
0015 struct xdp_umem_ring *umem_ring;
0016 struct xdp_rxtx_ring *rxtx_ring;
0017
0018 if (umem_queue)
0019 return struct_size(umem_ring, desc, q->nentries);
0020 return struct_size(rxtx_ring, desc, q->nentries);
0021 }
0022
0023 struct xsk_queue *xskq_create(u32 nentries, bool umem_queue)
0024 {
0025 struct xsk_queue *q;
0026 gfp_t gfp_flags;
0027 size_t size;
0028
0029 q = kzalloc(sizeof(*q), GFP_KERNEL);
0030 if (!q)
0031 return NULL;
0032
0033 q->nentries = nentries;
0034 q->ring_mask = nentries - 1;
0035
0036 gfp_flags = GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN |
0037 __GFP_COMP | __GFP_NORETRY;
0038 size = xskq_get_ring_size(q, umem_queue);
0039
0040 q->ring = (struct xdp_ring *)__get_free_pages(gfp_flags,
0041 get_order(size));
0042 if (!q->ring) {
0043 kfree(q);
0044 return NULL;
0045 }
0046
0047 return q;
0048 }
0049
0050 void xskq_destroy(struct xsk_queue *q)
0051 {
0052 if (!q)
0053 return;
0054
0055 page_frag_free(q->ring);
0056 kfree(q);
0057 }