eploop.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Test that we don't recursively generate completion events if an io_uring
  5. * fd is added to an epoll context, and the ring itself polls for events on
  6. * the epollfd. Older kernels will stop on overflow, newer kernels will
  7. * detect this earlier and abort correctly.
  8. */
  9. #include <stdio.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <sys/epoll.h>
  13. #include <sys/types.h>
  14. #include <poll.h>
  15. #include "liburing.h"
  16. #include "helpers.h"
  17. int main(int argc, char *argv[])
  18. {
  19. struct io_uring ring;
  20. struct io_uring_sqe *sqe;
  21. struct io_uring_cqe *cqe;
  22. struct epoll_event ev = { };
  23. int epollfd, ret, i;
  24. if (argc > 1)
  25. return T_EXIT_SKIP;
  26. ret = io_uring_queue_init(8, &ring, 0);
  27. if (ret) {
  28. fprintf(stderr, "Ring init failed: %d\n", ret);
  29. return T_EXIT_FAIL;
  30. }
  31. epollfd = epoll_create1(0);
  32. if (epollfd < 0) {
  33. perror("epoll_create");
  34. return T_EXIT_FAIL;
  35. }
  36. ev.events = EPOLLIN;
  37. ev.data.fd = ring.ring_fd;
  38. ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, ring.ring_fd, &ev);
  39. if (ret < 0) {
  40. perror("epoll_ctl");
  41. return T_EXIT_FAIL;
  42. }
  43. sqe = io_uring_get_sqe(&ring);
  44. io_uring_prep_poll_multishot(sqe, epollfd, POLLIN);
  45. sqe->user_data = 1;
  46. io_uring_submit(&ring);
  47. sqe = io_uring_get_sqe(&ring);
  48. sqe->user_data = 2;
  49. io_uring_prep_nop(sqe);
  50. io_uring_submit(&ring);
  51. for (i = 0; i < 2; i++) {
  52. ret = io_uring_wait_cqe(&ring, &cqe);
  53. if (ret) {
  54. fprintf(stderr, "wait_cqe ret = %d\n", ret);
  55. break;
  56. }
  57. io_uring_cqe_seen(&ring, cqe);
  58. }
  59. ret = io_uring_peek_cqe(&ring, &cqe);
  60. if (!ret) {
  61. fprintf(stderr, "Generated too many events\n");
  62. return T_EXIT_FAIL;
  63. }
  64. return T_EXIT_PASS;
  65. }