buf-ring-nommap.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Description: test IOU_PBUF_RING_MMAP with a ring setup with a ring
  5. * setup without mmap'ing sq/cq arrays
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <string.h>
  13. #include <sys/mman.h>
  14. #include "liburing.h"
  15. #include "helpers.h"
  16. static int bgid = 5;
  17. static int bid = 89;
  18. int main(int argc, char *argv[])
  19. {
  20. struct io_uring_buf_ring *br;
  21. struct io_uring_sqe *sqe;
  22. struct io_uring_cqe *cqe;
  23. struct io_uring ring;
  24. size_t ring_size;
  25. int ret, ring_mask, fds[2];
  26. struct io_uring_buf_reg reg = {
  27. .ring_entries = 1,
  28. .bgid = bgid,
  29. .flags = IOU_PBUF_RING_MMAP,
  30. };
  31. struct io_uring_params p = { };
  32. void *ring_mem;
  33. char buf[32];
  34. off_t off;
  35. if (argc > 1)
  36. return T_EXIT_SKIP;
  37. if (posix_memalign(&ring_mem, 16384, 16384))
  38. return T_EXIT_FAIL;
  39. memset(ring_mem, 0, 16384);
  40. p.flags = IORING_SETUP_NO_MMAP;
  41. ret = io_uring_queue_init_mem(1, &ring, &p, ring_mem, 16384);
  42. if (ret < 0) {
  43. if (ret == -EINVAL || ret == -ENOMEM) {
  44. free(ring_mem);
  45. return T_EXIT_SKIP;
  46. }
  47. fprintf(stderr, "queue init failed %d\n", ret);
  48. return T_EXIT_FAIL;
  49. }
  50. if (pipe(fds) < 0) {
  51. perror("pipe");
  52. return T_EXIT_FAIL;
  53. }
  54. ring_size = sizeof(struct io_uring_buf);
  55. ring_mask = io_uring_buf_ring_mask(1);
  56. ret = io_uring_register_buf_ring(&ring, &reg, 0);
  57. if (ret) {
  58. if (ret == -EINVAL) {
  59. free(ring_mem);
  60. return T_EXIT_SKIP;
  61. }
  62. fprintf(stderr, "reg buf ring: %d\n", ret);
  63. return T_EXIT_FAIL;
  64. }
  65. off = IORING_OFF_PBUF_RING |
  66. (unsigned long long) bgid << IORING_OFF_PBUF_SHIFT;
  67. br = mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
  68. MAP_SHARED | MAP_POPULATE, ring.ring_fd, off);
  69. if (br == MAP_FAILED) {
  70. if (errno == ENOMEM) {
  71. free(ring_mem);
  72. return T_EXIT_SKIP;
  73. }
  74. perror("mmap");
  75. return T_EXIT_FAIL;
  76. }
  77. io_uring_buf_ring_add(br, buf, sizeof(buf), bid, ring_mask, 0);
  78. io_uring_buf_ring_advance(br, 1);
  79. sqe = io_uring_get_sqe(&ring);
  80. io_uring_prep_read(sqe, fds[0], NULL, 0, 0);
  81. sqe->flags |= IOSQE_BUFFER_SELECT;
  82. sqe->buf_group = bgid;
  83. io_uring_submit(&ring);
  84. ret = write(fds[1], "Hello", 5);
  85. if (ret < 0) {
  86. perror("write");
  87. return T_EXIT_FAIL;
  88. } else if (ret != 5) {
  89. fprintf(stderr, "short write %d\n", ret);
  90. return T_EXIT_FAIL;
  91. }
  92. ret = io_uring_wait_cqe(&ring, &cqe);
  93. if (ret) {
  94. fprintf(stderr, "wait %d\n", ret);
  95. return T_EXIT_FAIL;
  96. }
  97. if (cqe->res < 0) {
  98. fprintf(stderr, "cqe res %d\n", cqe->res);
  99. return T_EXIT_FAIL;
  100. }
  101. if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
  102. fprintf(stderr, "buffer not selected in cqe\n");
  103. return T_EXIT_FAIL;
  104. }
  105. if ((cqe->flags >> IORING_CQE_BUFFER_SHIFT) != bid) {
  106. fprintf(stderr, "wrong buffer id returned\n");
  107. return T_EXIT_FAIL;
  108. }
  109. io_uring_cqe_seen(&ring, cqe);
  110. io_uring_queue_exit(&ring);
  111. free(ring_mem);
  112. return T_EXIT_PASS;
  113. }