reg-fd-only.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Test io_uring_setup with IORING_SETUP_REGISTERED_FD_ONLY
  5. *
  6. */
  7. #include <stdio.h>
  8. #include "helpers.h"
  9. #define NORMAL_PAGE_ENTRIES 8
  10. #define HUGE_PAGE_ENTRIES 512
  11. static int no_mmap;
  12. static int test_nops(struct io_uring *ring, int sq_size, int nr_nops)
  13. {
  14. struct io_uring_sqe *sqe;
  15. struct io_uring_cqe *cqe;
  16. int i, ret;
  17. do {
  18. int todo = nr_nops;
  19. if (todo > sq_size)
  20. todo = sq_size;
  21. for (i = 0; i < todo; i++) {
  22. sqe = io_uring_get_sqe(ring);
  23. io_uring_prep_nop(sqe);
  24. }
  25. ret = io_uring_submit(ring);
  26. if (ret != todo) {
  27. fprintf(stderr, "short submit %d\n", ret);
  28. return T_EXIT_FAIL;
  29. }
  30. for (i = 0; i < todo; i++) {
  31. ret = io_uring_wait_cqe(ring, &cqe);
  32. if (ret) {
  33. fprintf(stderr, "wait err %d\n", ret);
  34. return T_EXIT_FAIL;
  35. }
  36. io_uring_cqe_seen(ring, cqe);
  37. }
  38. nr_nops -= todo;
  39. } while (nr_nops);
  40. return T_EXIT_PASS;
  41. }
  42. static int test(int nentries, int ring_flags)
  43. {
  44. struct io_uring ring;
  45. unsigned values[2];
  46. int ret;
  47. ret = io_uring_queue_init(nentries, &ring,
  48. IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP |
  49. ring_flags);
  50. if (ret == -EINVAL) {
  51. no_mmap = 1;
  52. return T_EXIT_SKIP;
  53. } else if (ret == -ENOMEM) {
  54. fprintf(stdout, "Enable huge pages to test big rings\n");
  55. return T_EXIT_SKIP;
  56. } else if (ret) {
  57. fprintf(stderr, "ring setup failed: %d\n", ret);
  58. return T_EXIT_FAIL;
  59. }
  60. ret = io_uring_register_ring_fd(&ring);
  61. if (ret != -EEXIST) {
  62. fprintf(stderr, "registering already-registered ring fd should fail\n");
  63. goto err;
  64. }
  65. ret = io_uring_close_ring_fd(&ring);
  66. if (ret != -EBADF) {
  67. fprintf(stderr, "closing already-closed ring fd should fail\n");
  68. goto err;
  69. }
  70. /* Test a simple io_uring_register operation expected to work.
  71. * io_uring_register_iowq_max_workers is arbitrary.
  72. */
  73. values[0] = values[1] = 0;
  74. ret = io_uring_register_iowq_max_workers(&ring, values);
  75. if (ret || (values[0] == 0 && values[1] == 0)) {
  76. fprintf(stderr, "io_uring_register operation failed after closing ring fd\n");
  77. goto err;
  78. }
  79. ret = test_nops(&ring, nentries, nentries * 4);
  80. if (ret)
  81. goto err;
  82. io_uring_queue_exit(&ring);
  83. return T_EXIT_PASS;
  84. err:
  85. io_uring_queue_exit(&ring);
  86. return T_EXIT_FAIL;
  87. }
  88. int main(int argc, char *argv[])
  89. {
  90. int ret;
  91. if (argc > 1)
  92. return T_EXIT_SKIP;
  93. /* test single normal page */
  94. ret = test(NORMAL_PAGE_ENTRIES, 0);
  95. if (ret == T_EXIT_SKIP || no_mmap) {
  96. return T_EXIT_SKIP;
  97. } else if (ret != T_EXIT_PASS) {
  98. fprintf(stderr, "test 8 failed\n");
  99. return T_EXIT_FAIL;
  100. }
  101. /* test single normal page */
  102. ret = test(NORMAL_PAGE_ENTRIES, IORING_SETUP_SQPOLL);
  103. if (ret == T_EXIT_SKIP || no_mmap) {
  104. return T_EXIT_SKIP;
  105. } else if (ret != T_EXIT_PASS) {
  106. fprintf(stderr, "test 8 failed\n");
  107. return T_EXIT_FAIL;
  108. }
  109. /* test with entries requiring a huge page */
  110. ret = test(HUGE_PAGE_ENTRIES, 0);
  111. if (ret == T_EXIT_SKIP) {
  112. return T_EXIT_SKIP;
  113. } else if (ret != T_EXIT_PASS) {
  114. fprintf(stderr, "test 512 failed\n");
  115. return T_EXIT_FAIL;
  116. }
  117. return T_EXIT_PASS;
  118. }