1 // SPDX-License-Identifier: MIT
2
3 /*
4 * Description: tests bug fixed in
5 * "io_uring: don't gate task_work run on TIF_NOTIFY_SIGNAL"
6 *
7 * See: https://github.com/axboe/liburing/issues/665
8 */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include "helpers.h"
15 #include "liburing.h"
16
17 #define CHECK(x) \
18 do { \
19 if (!(x)) { \
20 fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
21 return -1; \
22 } \
23 } while (0)
24
pipe_bug(void)25 static int pipe_bug(void)
26 {
27 struct io_uring_params p;
28 struct io_uring ring;
29 struct io_uring_sqe *sqe;
30 struct io_uring_cqe *cqe;
31 char buf[1024];
32 int fds[2];
33 struct __kernel_timespec to = {
34 .tv_sec = 1
35 };
36
37 CHECK(pipe(fds) == 0);
38
39 memset(&p, 0, sizeof(p));
40 CHECK(t_create_ring_params(8, &ring, &p) == 0);
41
42 /* WRITE */
43 sqe = io_uring_get_sqe(&ring);
44 CHECK(sqe);
45 io_uring_prep_write(sqe, fds[1], "foobar", strlen("foobar"), 0); /* or -1 */
46 CHECK(io_uring_submit(&ring) == 1);
47 CHECK(io_uring_wait_cqe(&ring, &cqe) == 0);
48
49 io_uring_cqe_seen(&ring, cqe);
50
51 /* CLOSE */
52 sqe = io_uring_get_sqe(&ring);
53 CHECK(sqe);
54 io_uring_prep_close(sqe, fds[1]);
55 CHECK(io_uring_submit(&ring) == 1);
56 CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
57 io_uring_cqe_seen(&ring, cqe);
58
59 /* READ */
60 sqe = io_uring_get_sqe(&ring);
61 CHECK(sqe);
62 io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */
63 CHECK(io_uring_submit(&ring) == 1);
64 CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
65 io_uring_cqe_seen(&ring, cqe);
66 memset(buf, 0, sizeof(buf));
67
68 /* READ */
69 sqe = io_uring_get_sqe(&ring);
70 CHECK(sqe);
71 io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */
72 CHECK(io_uring_submit(&ring) == 1);
73 CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0);
74 io_uring_cqe_seen(&ring, cqe);
75
76 close(fds[0]);
77 io_uring_queue_exit(&ring);
78
79 return 0;
80 }
81
main(int argc,char * argv[])82 int main(int argc, char *argv[])
83 {
84 int i;
85
86 if (argc > 1)
87 return T_EXIT_SKIP;
88
89 for (i = 0; i < 10000; i++) {
90 if (pipe_bug())
91 return T_EXIT_FAIL;
92 }
93
94 return T_EXIT_PASS;
95 }
96