xsk_queue.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* XDP user-space ring structure
  3. * Copyright(c) 2018 Intel Corporation.
  4. */
  5. #include <linux/log2.h>
  6. #include <linux/slab.h>
  7. #include <linux/overflow.h>
  8. #include <net/xdp_sock_drv.h>
  9. #include "xsk_queue.h"
  10. static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue)
  11. {
  12. struct xdp_umem_ring *umem_ring;
  13. struct xdp_rxtx_ring *rxtx_ring;
  14. if (umem_queue)
  15. return struct_size(umem_ring, desc, q->nentries);
  16. return struct_size(rxtx_ring, desc, q->nentries);
  17. }
  18. struct xsk_queue *xskq_create(u32 nentries, bool umem_queue)
  19. {
  20. struct xsk_queue *q;
  21. gfp_t gfp_flags;
  22. size_t size;
  23. q = kzalloc(sizeof(*q), GFP_KERNEL);
  24. if (!q)
  25. return NULL;
  26. q->nentries = nentries;
  27. q->ring_mask = nentries - 1;
  28. gfp_flags = GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN |
  29. __GFP_COMP | __GFP_NORETRY;
  30. size = xskq_get_ring_size(q, umem_queue);
  31. q->ring = (struct xdp_ring *)__get_free_pages(gfp_flags,
  32. get_order(size));
  33. if (!q->ring) {
  34. kfree(q);
  35. return NULL;
  36. }
  37. return q;
  38. }
  39. void xskq_destroy(struct xsk_queue *q)
  40. {
  41. if (!q)
  42. return;
  43. page_frag_free(q->ring);
  44. kfree(q);
  45. }