sigfd-deadlock.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Description: test that sigfd reading/polling works. A regression test for
  5. * the upstream commit:
  6. *
  7. * fd7d6de22414 ("io_uring: don't recurse on tsk->sighand->siglock with signalfd")
  8. */
  9. #include <unistd.h>
  10. #include <sys/signalfd.h>
  11. #include <sys/epoll.h>
  12. #include <poll.h>
  13. #include <stdio.h>
  14. #include "liburing.h"
  15. #include "helpers.h"
  16. static int setup_signal(void)
  17. {
  18. sigset_t mask;
  19. int sfd;
  20. sigemptyset(&mask);
  21. sigaddset(&mask, SIGINT);
  22. sigprocmask(SIG_BLOCK, &mask, NULL);
  23. sfd = signalfd(-1, &mask, SFD_NONBLOCK);
  24. if (sfd < 0)
  25. perror("signalfd");
  26. return sfd;
  27. }
  28. static int test_uring(int sfd)
  29. {
  30. struct io_uring_sqe *sqe;
  31. struct io_uring_cqe *cqe;
  32. struct io_uring ring;
  33. int ret;
  34. ret = io_uring_queue_init(32, &ring, 0);
  35. if (ret)
  36. return T_EXIT_FAIL;
  37. sqe = io_uring_get_sqe(&ring);
  38. io_uring_prep_poll_add(sqe, sfd, POLLIN);
  39. ret = io_uring_submit(&ring);
  40. if (ret < 0) {
  41. ret = T_EXIT_FAIL;
  42. goto err_exit;
  43. }
  44. kill(getpid(), SIGINT);
  45. io_uring_wait_cqe(&ring, &cqe);
  46. if (cqe->res == -EOPNOTSUPP) {
  47. fprintf(stderr, "signalfd poll not supported\n");
  48. ret = T_EXIT_SKIP;
  49. } else if (cqe->res < 0) {
  50. fprintf(stderr, "poll failed: %d\n", cqe->res);
  51. ret = T_EXIT_FAIL;
  52. } else if (cqe->res & POLLIN) {
  53. ret = T_EXIT_PASS;
  54. } else {
  55. fprintf(stderr, "Unexpected poll mask %x\n", cqe->res);
  56. ret = T_EXIT_FAIL;
  57. }
  58. io_uring_cqe_seen(&ring, cqe);
  59. err_exit:
  60. io_uring_queue_exit(&ring);
  61. return ret;
  62. }
  63. int main(int argc, char *argv[])
  64. {
  65. int sfd, ret;
  66. if (argc > 1)
  67. return T_EXIT_PASS;
  68. sfd = setup_signal();
  69. if (sfd < 0)
  70. return T_EXIT_FAIL;
  71. ret = test_uring(sfd);
  72. if (ret == T_EXIT_FAIL)
  73. fprintf(stderr, "test_uring signalfd failed\n");
  74. close(sfd);
  75. return ret;
  76. }