xref: /aosp_15_r20/external/liburing/test/link-timeout.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker  * Description: run various linked timeout cases
4*25da2beaSAndroid Build Coastguard Worker  *
5*25da2beaSAndroid Build Coastguard Worker  */
6*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
7*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
8*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
9*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
10*25da2beaSAndroid Build Coastguard Worker #include <string.h>
11*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
12*25da2beaSAndroid Build Coastguard Worker #include <poll.h>
13*25da2beaSAndroid Build Coastguard Worker 
14*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
15*25da2beaSAndroid Build Coastguard Worker 
test_fail_lone_link_timeouts(struct io_uring * ring)16*25da2beaSAndroid Build Coastguard Worker static int test_fail_lone_link_timeouts(struct io_uring *ring)
17*25da2beaSAndroid Build Coastguard Worker {
18*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
19*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
20*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
21*25da2beaSAndroid Build Coastguard Worker 	int ret;
22*25da2beaSAndroid Build Coastguard Worker 
23*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
24*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
25*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
26*25da2beaSAndroid Build Coastguard Worker 		goto err;
27*25da2beaSAndroid Build Coastguard Worker 	}
28*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
29*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 1;
30*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 0;
31*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
32*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
33*25da2beaSAndroid Build Coastguard Worker 
34*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
35*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
36*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
37*25da2beaSAndroid Build Coastguard Worker 		goto err;
38*25da2beaSAndroid Build Coastguard Worker 	}
39*25da2beaSAndroid Build Coastguard Worker 
40*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
41*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
42*25da2beaSAndroid Build Coastguard Worker 		printf("wait completion %d\n", ret);
43*25da2beaSAndroid Build Coastguard Worker 		goto err;
44*25da2beaSAndroid Build Coastguard Worker 	}
45*25da2beaSAndroid Build Coastguard Worker 
46*25da2beaSAndroid Build Coastguard Worker 	if (cqe->user_data != 1) {
47*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "invalid user data %d\n", cqe->res);
48*25da2beaSAndroid Build Coastguard Worker 		goto err;
49*25da2beaSAndroid Build Coastguard Worker 	}
50*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res != -EINVAL) {
51*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "got %d, wanted -EINVAL\n", cqe->res);
52*25da2beaSAndroid Build Coastguard Worker 		goto err;
53*25da2beaSAndroid Build Coastguard Worker 	}
54*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
55*25da2beaSAndroid Build Coastguard Worker 
56*25da2beaSAndroid Build Coastguard Worker 	return 0;
57*25da2beaSAndroid Build Coastguard Worker err:
58*25da2beaSAndroid Build Coastguard Worker 	return 1;
59*25da2beaSAndroid Build Coastguard Worker }
60*25da2beaSAndroid Build Coastguard Worker 
test_fail_two_link_timeouts(struct io_uring * ring)61*25da2beaSAndroid Build Coastguard Worker static int test_fail_two_link_timeouts(struct io_uring *ring)
62*25da2beaSAndroid Build Coastguard Worker {
63*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
64*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
65*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
66*25da2beaSAndroid Build Coastguard Worker 	int ret, i, nr_wait;
67*25da2beaSAndroid Build Coastguard Worker 
68*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 1;
69*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 0;
70*25da2beaSAndroid Build Coastguard Worker 
71*25da2beaSAndroid Build Coastguard Worker 	/*
72*25da2beaSAndroid Build Coastguard Worker 	 * sqe_1: write destined to fail
73*25da2beaSAndroid Build Coastguard Worker 	 * use buf=NULL, to do that during the issuing stage
74*25da2beaSAndroid Build Coastguard Worker 	 */
75*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
76*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
77*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
78*25da2beaSAndroid Build Coastguard Worker 		goto err;
79*25da2beaSAndroid Build Coastguard Worker 	}
80*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_writev(sqe, 0, NULL, 1, 0);
81*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
82*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
83*25da2beaSAndroid Build Coastguard Worker 
84*25da2beaSAndroid Build Coastguard Worker 
85*25da2beaSAndroid Build Coastguard Worker 	/* sqe_2: valid linked timeout */
86*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
87*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
88*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
89*25da2beaSAndroid Build Coastguard Worker 		goto err;
90*25da2beaSAndroid Build Coastguard Worker 	}
91*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
92*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
93*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
94*25da2beaSAndroid Build Coastguard Worker 
95*25da2beaSAndroid Build Coastguard Worker 
96*25da2beaSAndroid Build Coastguard Worker 	/* sqe_3: invalid linked timeout */
97*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
98*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
99*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
100*25da2beaSAndroid Build Coastguard Worker 		goto err;
101*25da2beaSAndroid Build Coastguard Worker 	}
102*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
103*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
104*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
105*25da2beaSAndroid Build Coastguard Worker 
106*25da2beaSAndroid Build Coastguard Worker 	/* sqe_4: invalid linked timeout */
107*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
108*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
109*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
110*25da2beaSAndroid Build Coastguard Worker 		goto err;
111*25da2beaSAndroid Build Coastguard Worker 	}
112*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
113*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
114*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 4;
115*25da2beaSAndroid Build Coastguard Worker 
116*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
117*25da2beaSAndroid Build Coastguard Worker 	if (ret < 3) {
118*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
119*25da2beaSAndroid Build Coastguard Worker 		goto err;
120*25da2beaSAndroid Build Coastguard Worker 	}
121*25da2beaSAndroid Build Coastguard Worker 	nr_wait = ret;
122*25da2beaSAndroid Build Coastguard Worker 
123*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < nr_wait; i++) {
124*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
125*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
126*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
127*25da2beaSAndroid Build Coastguard Worker 			goto err;
128*25da2beaSAndroid Build Coastguard Worker 		}
129*25da2beaSAndroid Build Coastguard Worker 
130*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
131*25da2beaSAndroid Build Coastguard Worker 		case 1:
132*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EFAULT && cqe->res != -ECANCELED) {
133*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "write got %d, wanted -EFAULT "
134*25da2beaSAndroid Build Coastguard Worker 						"or -ECANCELED\n", cqe->res);
135*25da2beaSAndroid Build Coastguard Worker 				goto err;
136*25da2beaSAndroid Build Coastguard Worker 			}
137*25da2beaSAndroid Build Coastguard Worker 			break;
138*25da2beaSAndroid Build Coastguard Worker 		case 2:
139*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
140*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout got %d, wanted -ECACNCELED\n", cqe->res);
141*25da2beaSAndroid Build Coastguard Worker 				goto err;
142*25da2beaSAndroid Build Coastguard Worker 			}
143*25da2beaSAndroid Build Coastguard Worker 			break;
144*25da2beaSAndroid Build Coastguard Worker 		case 3:
145*25da2beaSAndroid Build Coastguard Worker 			/* fall through */
146*25da2beaSAndroid Build Coastguard Worker 		case 4:
147*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED && cqe->res != -EINVAL) {
148*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Invalid link timeout got %d"
149*25da2beaSAndroid Build Coastguard Worker 					", wanted -ECACNCELED || -EINVAL\n", cqe->res);
150*25da2beaSAndroid Build Coastguard Worker 				goto err;
151*25da2beaSAndroid Build Coastguard Worker 			}
152*25da2beaSAndroid Build Coastguard Worker 			break;
153*25da2beaSAndroid Build Coastguard Worker 		}
154*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
155*25da2beaSAndroid Build Coastguard Worker 	}
156*25da2beaSAndroid Build Coastguard Worker 
157*25da2beaSAndroid Build Coastguard Worker 	return 0;
158*25da2beaSAndroid Build Coastguard Worker err:
159*25da2beaSAndroid Build Coastguard Worker 	return 1;
160*25da2beaSAndroid Build Coastguard Worker }
161*25da2beaSAndroid Build Coastguard Worker 
162*25da2beaSAndroid Build Coastguard Worker /*
163*25da2beaSAndroid Build Coastguard Worker  * Test linked timeout with timeout (timeoutception)
164*25da2beaSAndroid Build Coastguard Worker  */
test_single_link_timeout_ception(struct io_uring * ring)165*25da2beaSAndroid Build Coastguard Worker static int test_single_link_timeout_ception(struct io_uring *ring)
166*25da2beaSAndroid Build Coastguard Worker {
167*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts1, ts2;
168*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
169*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
170*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
171*25da2beaSAndroid Build Coastguard Worker 
172*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
173*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
174*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
175*25da2beaSAndroid Build Coastguard Worker 		goto err;
176*25da2beaSAndroid Build Coastguard Worker 	}
177*25da2beaSAndroid Build Coastguard Worker 
178*25da2beaSAndroid Build Coastguard Worker 	ts1.tv_sec = 1;
179*25da2beaSAndroid Build Coastguard Worker 	ts1.tv_nsec = 0;
180*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts1, -1U, 0);
181*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
182*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
183*25da2beaSAndroid Build Coastguard Worker 
184*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
185*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
186*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
187*25da2beaSAndroid Build Coastguard Worker 		goto err;
188*25da2beaSAndroid Build Coastguard Worker 	}
189*25da2beaSAndroid Build Coastguard Worker 
190*25da2beaSAndroid Build Coastguard Worker 	ts2.tv_sec = 2;
191*25da2beaSAndroid Build Coastguard Worker 	ts2.tv_nsec = 0;
192*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts2, 0);
193*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
194*25da2beaSAndroid Build Coastguard Worker 
195*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
196*25da2beaSAndroid Build Coastguard Worker 	if (ret != 2) {
197*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
198*25da2beaSAndroid Build Coastguard Worker 		goto err;
199*25da2beaSAndroid Build Coastguard Worker 	}
200*25da2beaSAndroid Build Coastguard Worker 
201*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
202*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
203*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
204*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
205*25da2beaSAndroid Build Coastguard Worker 			goto err;
206*25da2beaSAndroid Build Coastguard Worker 		}
207*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
208*25da2beaSAndroid Build Coastguard Worker 		case 1:
209*25da2beaSAndroid Build Coastguard Worker 			/* newer kernels allow timeout links */
210*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EINVAL && cqe->res != -ETIME) {
211*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Timeout got %d, wanted "
212*25da2beaSAndroid Build Coastguard Worker 					"-EINVAL or -ETIME\n", cqe->res);
213*25da2beaSAndroid Build Coastguard Worker 				goto err;
214*25da2beaSAndroid Build Coastguard Worker 			}
215*25da2beaSAndroid Build Coastguard Worker 			break;
216*25da2beaSAndroid Build Coastguard Worker 		case 2:
217*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
218*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout got %d, wanted -ECANCELED\n", cqe->res);
219*25da2beaSAndroid Build Coastguard Worker 				goto err;
220*25da2beaSAndroid Build Coastguard Worker 			}
221*25da2beaSAndroid Build Coastguard Worker 			break;
222*25da2beaSAndroid Build Coastguard Worker 		}
223*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
224*25da2beaSAndroid Build Coastguard Worker 	}
225*25da2beaSAndroid Build Coastguard Worker 
226*25da2beaSAndroid Build Coastguard Worker 	return 0;
227*25da2beaSAndroid Build Coastguard Worker err:
228*25da2beaSAndroid Build Coastguard Worker 	return 1;
229*25da2beaSAndroid Build Coastguard Worker }
230*25da2beaSAndroid Build Coastguard Worker 
231*25da2beaSAndroid Build Coastguard Worker /*
232*25da2beaSAndroid Build Coastguard Worker  * Test linked timeout with NOP
233*25da2beaSAndroid Build Coastguard Worker  */
test_single_link_timeout_nop(struct io_uring * ring)234*25da2beaSAndroid Build Coastguard Worker static int test_single_link_timeout_nop(struct io_uring *ring)
235*25da2beaSAndroid Build Coastguard Worker {
236*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
237*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
238*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
239*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
240*25da2beaSAndroid Build Coastguard Worker 
241*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
242*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
243*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
244*25da2beaSAndroid Build Coastguard Worker 		goto err;
245*25da2beaSAndroid Build Coastguard Worker 	}
246*25da2beaSAndroid Build Coastguard Worker 
247*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
248*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
249*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
250*25da2beaSAndroid Build Coastguard Worker 
251*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
252*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
253*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
254*25da2beaSAndroid Build Coastguard Worker 		goto err;
255*25da2beaSAndroid Build Coastguard Worker 	}
256*25da2beaSAndroid Build Coastguard Worker 
257*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 1;
258*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 0;
259*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
260*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
261*25da2beaSAndroid Build Coastguard Worker 
262*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
263*25da2beaSAndroid Build Coastguard Worker 	if (ret != 2) {
264*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
265*25da2beaSAndroid Build Coastguard Worker 		goto err;
266*25da2beaSAndroid Build Coastguard Worker 	}
267*25da2beaSAndroid Build Coastguard Worker 
268*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
269*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
270*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
271*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
272*25da2beaSAndroid Build Coastguard Worker 			goto err;
273*25da2beaSAndroid Build Coastguard Worker 		}
274*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
275*25da2beaSAndroid Build Coastguard Worker 		case 1:
276*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res) {
277*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "NOP got %d, wanted 0\n", cqe->res);
278*25da2beaSAndroid Build Coastguard Worker 				goto err;
279*25da2beaSAndroid Build Coastguard Worker 			}
280*25da2beaSAndroid Build Coastguard Worker 			break;
281*25da2beaSAndroid Build Coastguard Worker 		case 2:
282*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
283*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout got %d, wanted -ECACNCELED\n", cqe->res);
284*25da2beaSAndroid Build Coastguard Worker 				goto err;
285*25da2beaSAndroid Build Coastguard Worker 			}
286*25da2beaSAndroid Build Coastguard Worker 			break;
287*25da2beaSAndroid Build Coastguard Worker 		}
288*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
289*25da2beaSAndroid Build Coastguard Worker 	}
290*25da2beaSAndroid Build Coastguard Worker 
291*25da2beaSAndroid Build Coastguard Worker 	return 0;
292*25da2beaSAndroid Build Coastguard Worker err:
293*25da2beaSAndroid Build Coastguard Worker 	return 1;
294*25da2beaSAndroid Build Coastguard Worker }
295*25da2beaSAndroid Build Coastguard Worker 
296*25da2beaSAndroid Build Coastguard Worker /*
297*25da2beaSAndroid Build Coastguard Worker  * Test read that will not complete, with a linked timeout behind it that
298*25da2beaSAndroid Build Coastguard Worker  * has errors in the SQE
299*25da2beaSAndroid Build Coastguard Worker  */
test_single_link_timeout_error(struct io_uring * ring)300*25da2beaSAndroid Build Coastguard Worker static int test_single_link_timeout_error(struct io_uring *ring)
301*25da2beaSAndroid Build Coastguard Worker {
302*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
303*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
304*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
305*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
306*25da2beaSAndroid Build Coastguard Worker 	struct iovec iov;
307*25da2beaSAndroid Build Coastguard Worker 	char buffer[128];
308*25da2beaSAndroid Build Coastguard Worker 
309*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
310*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
311*25da2beaSAndroid Build Coastguard Worker 		return 1;
312*25da2beaSAndroid Build Coastguard Worker 	}
313*25da2beaSAndroid Build Coastguard Worker 
314*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
315*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
316*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
317*25da2beaSAndroid Build Coastguard Worker 		goto err;
318*25da2beaSAndroid Build Coastguard Worker 	}
319*25da2beaSAndroid Build Coastguard Worker 
320*25da2beaSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
321*25da2beaSAndroid Build Coastguard Worker 	iov.iov_len = sizeof(buffer);
322*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
323*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
324*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
325*25da2beaSAndroid Build Coastguard Worker 
326*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
327*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
328*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
329*25da2beaSAndroid Build Coastguard Worker 		goto err;
330*25da2beaSAndroid Build Coastguard Worker 	}
331*25da2beaSAndroid Build Coastguard Worker 
332*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 1;
333*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 0;
334*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
335*25da2beaSAndroid Build Coastguard Worker 	/* set invalid field, it'll get failed */
336*25da2beaSAndroid Build Coastguard Worker 	sqe->ioprio = 89;
337*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
338*25da2beaSAndroid Build Coastguard Worker 
339*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
340*25da2beaSAndroid Build Coastguard Worker 	if (ret != 2) {
341*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
342*25da2beaSAndroid Build Coastguard Worker 		goto err;
343*25da2beaSAndroid Build Coastguard Worker 	}
344*25da2beaSAndroid Build Coastguard Worker 
345*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
346*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
347*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
348*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
349*25da2beaSAndroid Build Coastguard Worker 			goto err;
350*25da2beaSAndroid Build Coastguard Worker 		}
351*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
352*25da2beaSAndroid Build Coastguard Worker 		case 1:
353*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
354*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Read got %d, wanted -ECANCELED\n",
355*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
356*25da2beaSAndroid Build Coastguard Worker 				goto err;
357*25da2beaSAndroid Build Coastguard Worker 			}
358*25da2beaSAndroid Build Coastguard Worker 			break;
359*25da2beaSAndroid Build Coastguard Worker 		case 2:
360*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EINVAL) {
361*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout got %d, wanted -EINVAL\n", cqe->res);
362*25da2beaSAndroid Build Coastguard Worker 				goto err;
363*25da2beaSAndroid Build Coastguard Worker 			}
364*25da2beaSAndroid Build Coastguard Worker 			break;
365*25da2beaSAndroid Build Coastguard Worker 		}
366*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
367*25da2beaSAndroid Build Coastguard Worker 	}
368*25da2beaSAndroid Build Coastguard Worker 
369*25da2beaSAndroid Build Coastguard Worker 	return 0;
370*25da2beaSAndroid Build Coastguard Worker err:
371*25da2beaSAndroid Build Coastguard Worker 	return 1;
372*25da2beaSAndroid Build Coastguard Worker }
373*25da2beaSAndroid Build Coastguard Worker 
374*25da2beaSAndroid Build Coastguard Worker /*
375*25da2beaSAndroid Build Coastguard Worker  * Test read that will complete, with a linked timeout behind it
376*25da2beaSAndroid Build Coastguard Worker  */
test_single_link_no_timeout(struct io_uring * ring)377*25da2beaSAndroid Build Coastguard Worker static int test_single_link_no_timeout(struct io_uring *ring)
378*25da2beaSAndroid Build Coastguard Worker {
379*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
380*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
381*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
382*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
383*25da2beaSAndroid Build Coastguard Worker 	struct iovec iov;
384*25da2beaSAndroid Build Coastguard Worker 	char buffer[128];
385*25da2beaSAndroid Build Coastguard Worker 
386*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
387*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
388*25da2beaSAndroid Build Coastguard Worker 		return 1;
389*25da2beaSAndroid Build Coastguard Worker 	}
390*25da2beaSAndroid Build Coastguard Worker 
391*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
392*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
393*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
394*25da2beaSAndroid Build Coastguard Worker 		goto err;
395*25da2beaSAndroid Build Coastguard Worker 	}
396*25da2beaSAndroid Build Coastguard Worker 
397*25da2beaSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
398*25da2beaSAndroid Build Coastguard Worker 	iov.iov_len = sizeof(buffer);
399*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
400*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
401*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
402*25da2beaSAndroid Build Coastguard Worker 
403*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
404*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
405*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
406*25da2beaSAndroid Build Coastguard Worker 		goto err;
407*25da2beaSAndroid Build Coastguard Worker 	}
408*25da2beaSAndroid Build Coastguard Worker 
409*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 1;
410*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 0;
411*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
412*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
413*25da2beaSAndroid Build Coastguard Worker 
414*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
415*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
416*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
417*25da2beaSAndroid Build Coastguard Worker 		goto err;
418*25da2beaSAndroid Build Coastguard Worker 	}
419*25da2beaSAndroid Build Coastguard Worker 
420*25da2beaSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
421*25da2beaSAndroid Build Coastguard Worker 	iov.iov_len = sizeof(buffer);
422*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_writev(sqe, fds[1], &iov, 1, 0);
423*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
424*25da2beaSAndroid Build Coastguard Worker 
425*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
426*25da2beaSAndroid Build Coastguard Worker 	if (ret != 3) {
427*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
428*25da2beaSAndroid Build Coastguard Worker 		goto err;
429*25da2beaSAndroid Build Coastguard Worker 	}
430*25da2beaSAndroid Build Coastguard Worker 
431*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
432*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
433*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
434*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
435*25da2beaSAndroid Build Coastguard Worker 			goto err;
436*25da2beaSAndroid Build Coastguard Worker 		}
437*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
438*25da2beaSAndroid Build Coastguard Worker 		case 1:
439*25da2beaSAndroid Build Coastguard Worker 		case 3:
440*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != sizeof(buffer)) {
441*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "R/W got %d, wanted %d\n", cqe->res,
442*25da2beaSAndroid Build Coastguard Worker 						(int) sizeof(buffer));
443*25da2beaSAndroid Build Coastguard Worker 				goto err;
444*25da2beaSAndroid Build Coastguard Worker 			}
445*25da2beaSAndroid Build Coastguard Worker 			break;
446*25da2beaSAndroid Build Coastguard Worker 		case 2:
447*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
448*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout %d, wanted -ECANCELED\n",
449*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
450*25da2beaSAndroid Build Coastguard Worker 				goto err;
451*25da2beaSAndroid Build Coastguard Worker 			}
452*25da2beaSAndroid Build Coastguard Worker 			break;
453*25da2beaSAndroid Build Coastguard Worker 		}
454*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
455*25da2beaSAndroid Build Coastguard Worker 	}
456*25da2beaSAndroid Build Coastguard Worker 
457*25da2beaSAndroid Build Coastguard Worker 	return 0;
458*25da2beaSAndroid Build Coastguard Worker err:
459*25da2beaSAndroid Build Coastguard Worker 	return 1;
460*25da2beaSAndroid Build Coastguard Worker }
461*25da2beaSAndroid Build Coastguard Worker 
462*25da2beaSAndroid Build Coastguard Worker /*
463*25da2beaSAndroid Build Coastguard Worker  * Test read that will not complete, with a linked timeout behind it
464*25da2beaSAndroid Build Coastguard Worker  */
test_single_link_timeout(struct io_uring * ring,unsigned nsec)465*25da2beaSAndroid Build Coastguard Worker static int test_single_link_timeout(struct io_uring *ring, unsigned nsec)
466*25da2beaSAndroid Build Coastguard Worker {
467*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
468*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
469*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
470*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
471*25da2beaSAndroid Build Coastguard Worker 	struct iovec iov;
472*25da2beaSAndroid Build Coastguard Worker 	char buffer[128];
473*25da2beaSAndroid Build Coastguard Worker 
474*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
475*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
476*25da2beaSAndroid Build Coastguard Worker 		return 1;
477*25da2beaSAndroid Build Coastguard Worker 	}
478*25da2beaSAndroid Build Coastguard Worker 
479*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
480*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
481*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
482*25da2beaSAndroid Build Coastguard Worker 		goto err;
483*25da2beaSAndroid Build Coastguard Worker 	}
484*25da2beaSAndroid Build Coastguard Worker 
485*25da2beaSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
486*25da2beaSAndroid Build Coastguard Worker 	iov.iov_len = sizeof(buffer);
487*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
488*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
489*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
490*25da2beaSAndroid Build Coastguard Worker 
491*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
492*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
493*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
494*25da2beaSAndroid Build Coastguard Worker 		goto err;
495*25da2beaSAndroid Build Coastguard Worker 	}
496*25da2beaSAndroid Build Coastguard Worker 
497*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 0;
498*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = nsec;
499*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
500*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
501*25da2beaSAndroid Build Coastguard Worker 
502*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
503*25da2beaSAndroid Build Coastguard Worker 	if (ret != 2) {
504*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
505*25da2beaSAndroid Build Coastguard Worker 		goto err;
506*25da2beaSAndroid Build Coastguard Worker 	}
507*25da2beaSAndroid Build Coastguard Worker 
508*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
509*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
510*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
511*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
512*25da2beaSAndroid Build Coastguard Worker 			goto err;
513*25da2beaSAndroid Build Coastguard Worker 		}
514*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
515*25da2beaSAndroid Build Coastguard Worker 		case 1:
516*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
517*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Read got %d\n", cqe->res);
518*25da2beaSAndroid Build Coastguard Worker 				goto err;
519*25da2beaSAndroid Build Coastguard Worker 			}
520*25da2beaSAndroid Build Coastguard Worker 			break;
521*25da2beaSAndroid Build Coastguard Worker 		case 2:
522*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EALREADY && cqe->res != -ETIME &&
523*25da2beaSAndroid Build Coastguard Worker 			    cqe->res != 0) {
524*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout got %d\n", cqe->res);
525*25da2beaSAndroid Build Coastguard Worker 				goto err;
526*25da2beaSAndroid Build Coastguard Worker 			}
527*25da2beaSAndroid Build Coastguard Worker 			break;
528*25da2beaSAndroid Build Coastguard Worker 		}
529*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
530*25da2beaSAndroid Build Coastguard Worker 	}
531*25da2beaSAndroid Build Coastguard Worker 
532*25da2beaSAndroid Build Coastguard Worker 	close(fds[0]);
533*25da2beaSAndroid Build Coastguard Worker 	close(fds[1]);
534*25da2beaSAndroid Build Coastguard Worker 	return 0;
535*25da2beaSAndroid Build Coastguard Worker err:
536*25da2beaSAndroid Build Coastguard Worker 	return 1;
537*25da2beaSAndroid Build Coastguard Worker }
538*25da2beaSAndroid Build Coastguard Worker 
test_timeout_link_chain1(struct io_uring * ring)539*25da2beaSAndroid Build Coastguard Worker static int test_timeout_link_chain1(struct io_uring *ring)
540*25da2beaSAndroid Build Coastguard Worker {
541*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
542*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
543*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
544*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
545*25da2beaSAndroid Build Coastguard Worker 	struct iovec iov;
546*25da2beaSAndroid Build Coastguard Worker 	char buffer[128];
547*25da2beaSAndroid Build Coastguard Worker 
548*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
549*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
550*25da2beaSAndroid Build Coastguard Worker 		return 1;
551*25da2beaSAndroid Build Coastguard Worker 	}
552*25da2beaSAndroid Build Coastguard Worker 
553*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
554*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
555*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
556*25da2beaSAndroid Build Coastguard Worker 		goto err;
557*25da2beaSAndroid Build Coastguard Worker 	}
558*25da2beaSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
559*25da2beaSAndroid Build Coastguard Worker 	iov.iov_len = sizeof(buffer);
560*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
561*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
562*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
563*25da2beaSAndroid Build Coastguard Worker 
564*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
565*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
566*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
567*25da2beaSAndroid Build Coastguard Worker 		goto err;
568*25da2beaSAndroid Build Coastguard Worker 	}
569*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 0;
570*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 1000000;
571*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
572*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
573*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
574*25da2beaSAndroid Build Coastguard Worker 
575*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
576*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
577*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
578*25da2beaSAndroid Build Coastguard Worker 		goto err;
579*25da2beaSAndroid Build Coastguard Worker 	}
580*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
581*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
582*25da2beaSAndroid Build Coastguard Worker 
583*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
584*25da2beaSAndroid Build Coastguard Worker 	if (ret != 3) {
585*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
586*25da2beaSAndroid Build Coastguard Worker 		goto err;
587*25da2beaSAndroid Build Coastguard Worker 	}
588*25da2beaSAndroid Build Coastguard Worker 
589*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
590*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
591*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
592*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
593*25da2beaSAndroid Build Coastguard Worker 			goto err;
594*25da2beaSAndroid Build Coastguard Worker 		}
595*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
596*25da2beaSAndroid Build Coastguard Worker 		case 1:
597*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
598*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
599*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
600*25da2beaSAndroid Build Coastguard Worker 				goto err;
601*25da2beaSAndroid Build Coastguard Worker 			}
602*25da2beaSAndroid Build Coastguard Worker 			break;
603*25da2beaSAndroid Build Coastguard Worker 		case 2:
604*25da2beaSAndroid Build Coastguard Worker 			/* FASTPOLL kernels can cancel successfully */
605*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -EALREADY && cqe->res != -ETIME) {
606*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
607*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
608*25da2beaSAndroid Build Coastguard Worker 				goto err;
609*25da2beaSAndroid Build Coastguard Worker 			}
610*25da2beaSAndroid Build Coastguard Worker 			break;
611*25da2beaSAndroid Build Coastguard Worker 		case 3:
612*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
613*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
614*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
615*25da2beaSAndroid Build Coastguard Worker 				goto err;
616*25da2beaSAndroid Build Coastguard Worker 			}
617*25da2beaSAndroid Build Coastguard Worker 			break;
618*25da2beaSAndroid Build Coastguard Worker 		}
619*25da2beaSAndroid Build Coastguard Worker 
620*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
621*25da2beaSAndroid Build Coastguard Worker 	}
622*25da2beaSAndroid Build Coastguard Worker 
623*25da2beaSAndroid Build Coastguard Worker 	close(fds[0]);
624*25da2beaSAndroid Build Coastguard Worker 	close(fds[1]);
625*25da2beaSAndroid Build Coastguard Worker 	return 0;
626*25da2beaSAndroid Build Coastguard Worker err:
627*25da2beaSAndroid Build Coastguard Worker 	return 1;
628*25da2beaSAndroid Build Coastguard Worker }
629*25da2beaSAndroid Build Coastguard Worker 
test_timeout_link_chain2(struct io_uring * ring)630*25da2beaSAndroid Build Coastguard Worker static int test_timeout_link_chain2(struct io_uring *ring)
631*25da2beaSAndroid Build Coastguard Worker {
632*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
633*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
634*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
635*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
636*25da2beaSAndroid Build Coastguard Worker 
637*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
638*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
639*25da2beaSAndroid Build Coastguard Worker 		return 1;
640*25da2beaSAndroid Build Coastguard Worker 	}
641*25da2beaSAndroid Build Coastguard Worker 
642*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
643*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
644*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
645*25da2beaSAndroid Build Coastguard Worker 		goto err;
646*25da2beaSAndroid Build Coastguard Worker 	}
647*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_poll_add(sqe, fds[0], POLLIN);
648*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
649*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
650*25da2beaSAndroid Build Coastguard Worker 
651*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
652*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
653*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
654*25da2beaSAndroid Build Coastguard Worker 		goto err;
655*25da2beaSAndroid Build Coastguard Worker 	}
656*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 0;
657*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 1000000;
658*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
659*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
660*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
661*25da2beaSAndroid Build Coastguard Worker 
662*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
663*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
664*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
665*25da2beaSAndroid Build Coastguard Worker 		goto err;
666*25da2beaSAndroid Build Coastguard Worker 	}
667*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
668*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
669*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
670*25da2beaSAndroid Build Coastguard Worker 
671*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
672*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
673*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
674*25da2beaSAndroid Build Coastguard Worker 		goto err;
675*25da2beaSAndroid Build Coastguard Worker 	}
676*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
677*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 4;
678*25da2beaSAndroid Build Coastguard Worker 
679*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
680*25da2beaSAndroid Build Coastguard Worker 	if (ret != 4) {
681*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
682*25da2beaSAndroid Build Coastguard Worker 		goto err;
683*25da2beaSAndroid Build Coastguard Worker 	}
684*25da2beaSAndroid Build Coastguard Worker 
685*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 4; i++) {
686*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
687*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
688*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
689*25da2beaSAndroid Build Coastguard Worker 			goto err;
690*25da2beaSAndroid Build Coastguard Worker 		}
691*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
692*25da2beaSAndroid Build Coastguard Worker 		/* poll cancel really should return -ECANCEL... */
693*25da2beaSAndroid Build Coastguard Worker 		case 1:
694*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
695*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
696*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
697*25da2beaSAndroid Build Coastguard Worker 				goto err;
698*25da2beaSAndroid Build Coastguard Worker 			}
699*25da2beaSAndroid Build Coastguard Worker 			break;
700*25da2beaSAndroid Build Coastguard Worker 		case 2:
701*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
702*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
703*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
704*25da2beaSAndroid Build Coastguard Worker 				goto err;
705*25da2beaSAndroid Build Coastguard Worker 			}
706*25da2beaSAndroid Build Coastguard Worker 			break;
707*25da2beaSAndroid Build Coastguard Worker 		case 3:
708*25da2beaSAndroid Build Coastguard Worker 		case 4:
709*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
710*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
711*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
712*25da2beaSAndroid Build Coastguard Worker 				goto err;
713*25da2beaSAndroid Build Coastguard Worker 			}
714*25da2beaSAndroid Build Coastguard Worker 			break;
715*25da2beaSAndroid Build Coastguard Worker 		}
716*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
717*25da2beaSAndroid Build Coastguard Worker 	}
718*25da2beaSAndroid Build Coastguard Worker 
719*25da2beaSAndroid Build Coastguard Worker 	close(fds[0]);
720*25da2beaSAndroid Build Coastguard Worker 	close(fds[1]);
721*25da2beaSAndroid Build Coastguard Worker 	return 0;
722*25da2beaSAndroid Build Coastguard Worker err:
723*25da2beaSAndroid Build Coastguard Worker 	return 1;
724*25da2beaSAndroid Build Coastguard Worker }
725*25da2beaSAndroid Build Coastguard Worker 
test_timeout_link_chain3(struct io_uring * ring)726*25da2beaSAndroid Build Coastguard Worker static int test_timeout_link_chain3(struct io_uring *ring)
727*25da2beaSAndroid Build Coastguard Worker {
728*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
729*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
730*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
731*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
732*25da2beaSAndroid Build Coastguard Worker 
733*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
734*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
735*25da2beaSAndroid Build Coastguard Worker 		return 1;
736*25da2beaSAndroid Build Coastguard Worker 	}
737*25da2beaSAndroid Build Coastguard Worker 
738*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
739*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
740*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
741*25da2beaSAndroid Build Coastguard Worker 		goto err;
742*25da2beaSAndroid Build Coastguard Worker 	}
743*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_poll_add(sqe, fds[0], POLLIN);
744*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
745*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
746*25da2beaSAndroid Build Coastguard Worker 
747*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
748*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
749*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
750*25da2beaSAndroid Build Coastguard Worker 		goto err;
751*25da2beaSAndroid Build Coastguard Worker 	}
752*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 0;
753*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 1000000;
754*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
755*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
756*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
757*25da2beaSAndroid Build Coastguard Worker 
758*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
759*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
760*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
761*25da2beaSAndroid Build Coastguard Worker 		goto err;
762*25da2beaSAndroid Build Coastguard Worker 	}
763*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
764*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
765*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
766*25da2beaSAndroid Build Coastguard Worker 
767*25da2beaSAndroid Build Coastguard Worker 	/* POLL -> TIMEOUT -> NOP */
768*25da2beaSAndroid Build Coastguard Worker 
769*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
770*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
771*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
772*25da2beaSAndroid Build Coastguard Worker 		goto err;
773*25da2beaSAndroid Build Coastguard Worker 	}
774*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_poll_add(sqe, fds[0], POLLIN);
775*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
776*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 4;
777*25da2beaSAndroid Build Coastguard Worker 
778*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
779*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
780*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
781*25da2beaSAndroid Build Coastguard Worker 		goto err;
782*25da2beaSAndroid Build Coastguard Worker 	}
783*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 0;
784*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 1000000;
785*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
786*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 5;
787*25da2beaSAndroid Build Coastguard Worker 
788*25da2beaSAndroid Build Coastguard Worker 	/* poll on pipe + timeout */
789*25da2beaSAndroid Build Coastguard Worker 
790*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
791*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
792*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
793*25da2beaSAndroid Build Coastguard Worker 		goto err;
794*25da2beaSAndroid Build Coastguard Worker 	}
795*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
796*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 6;
797*25da2beaSAndroid Build Coastguard Worker 
798*25da2beaSAndroid Build Coastguard Worker 	/* nop */
799*25da2beaSAndroid Build Coastguard Worker 
800*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
801*25da2beaSAndroid Build Coastguard Worker 	if (ret != 6) {
802*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
803*25da2beaSAndroid Build Coastguard Worker 		goto err;
804*25da2beaSAndroid Build Coastguard Worker 	}
805*25da2beaSAndroid Build Coastguard Worker 
806*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 6; i++) {
807*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
808*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
809*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
810*25da2beaSAndroid Build Coastguard Worker 			goto err;
811*25da2beaSAndroid Build Coastguard Worker 		}
812*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
813*25da2beaSAndroid Build Coastguard Worker 		case 2:
814*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
815*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
816*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
817*25da2beaSAndroid Build Coastguard Worker 				goto err;
818*25da2beaSAndroid Build Coastguard Worker 			}
819*25da2beaSAndroid Build Coastguard Worker 			break;
820*25da2beaSAndroid Build Coastguard Worker 		case 1:
821*25da2beaSAndroid Build Coastguard Worker 		case 3:
822*25da2beaSAndroid Build Coastguard Worker 		case 4:
823*25da2beaSAndroid Build Coastguard Worker 		case 5:
824*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
825*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
826*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
827*25da2beaSAndroid Build Coastguard Worker 				goto err;
828*25da2beaSAndroid Build Coastguard Worker 			}
829*25da2beaSAndroid Build Coastguard Worker 			break;
830*25da2beaSAndroid Build Coastguard Worker 		case 6:
831*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res) {
832*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
833*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
834*25da2beaSAndroid Build Coastguard Worker 				goto err;
835*25da2beaSAndroid Build Coastguard Worker 			}
836*25da2beaSAndroid Build Coastguard Worker 			break;
837*25da2beaSAndroid Build Coastguard Worker 		}
838*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
839*25da2beaSAndroid Build Coastguard Worker 	}
840*25da2beaSAndroid Build Coastguard Worker 
841*25da2beaSAndroid Build Coastguard Worker 	close(fds[0]);
842*25da2beaSAndroid Build Coastguard Worker 	close(fds[1]);
843*25da2beaSAndroid Build Coastguard Worker 	return 0;
844*25da2beaSAndroid Build Coastguard Worker err:
845*25da2beaSAndroid Build Coastguard Worker 	return 1;
846*25da2beaSAndroid Build Coastguard Worker }
847*25da2beaSAndroid Build Coastguard Worker 
test_timeout_link_chain4(struct io_uring * ring)848*25da2beaSAndroid Build Coastguard Worker static int test_timeout_link_chain4(struct io_uring *ring)
849*25da2beaSAndroid Build Coastguard Worker {
850*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
851*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
852*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
853*25da2beaSAndroid Build Coastguard Worker 	int fds[2], ret, i;
854*25da2beaSAndroid Build Coastguard Worker 
855*25da2beaSAndroid Build Coastguard Worker 	if (pipe(fds)) {
856*25da2beaSAndroid Build Coastguard Worker 		perror("pipe");
857*25da2beaSAndroid Build Coastguard Worker 		return 1;
858*25da2beaSAndroid Build Coastguard Worker 	}
859*25da2beaSAndroid Build Coastguard Worker 
860*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
861*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
862*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
863*25da2beaSAndroid Build Coastguard Worker 		goto err;
864*25da2beaSAndroid Build Coastguard Worker 	}
865*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
866*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
867*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
868*25da2beaSAndroid Build Coastguard Worker 
869*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
870*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
871*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
872*25da2beaSAndroid Build Coastguard Worker 		goto err;
873*25da2beaSAndroid Build Coastguard Worker 	}
874*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_poll_add(sqe, fds[0], POLLIN);
875*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
876*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
877*25da2beaSAndroid Build Coastguard Worker 
878*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
879*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
880*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
881*25da2beaSAndroid Build Coastguard Worker 		goto err;
882*25da2beaSAndroid Build Coastguard Worker 	}
883*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = 0;
884*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = 1000000;
885*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts, 0);
886*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
887*25da2beaSAndroid Build Coastguard Worker 
888*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
889*25da2beaSAndroid Build Coastguard Worker 	if (ret != 3) {
890*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
891*25da2beaSAndroid Build Coastguard Worker 		goto err;
892*25da2beaSAndroid Build Coastguard Worker 	}
893*25da2beaSAndroid Build Coastguard Worker 
894*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
895*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
896*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
897*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
898*25da2beaSAndroid Build Coastguard Worker 			goto err;
899*25da2beaSAndroid Build Coastguard Worker 		}
900*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
901*25da2beaSAndroid Build Coastguard Worker 		/* poll cancel really should return -ECANCEL... */
902*25da2beaSAndroid Build Coastguard Worker 		case 1:
903*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res) {
904*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
905*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
906*25da2beaSAndroid Build Coastguard Worker 				goto err;
907*25da2beaSAndroid Build Coastguard Worker 			}
908*25da2beaSAndroid Build Coastguard Worker 			break;
909*25da2beaSAndroid Build Coastguard Worker 		case 2:
910*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
911*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
912*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
913*25da2beaSAndroid Build Coastguard Worker 				goto err;
914*25da2beaSAndroid Build Coastguard Worker 			}
915*25da2beaSAndroid Build Coastguard Worker 			break;
916*25da2beaSAndroid Build Coastguard Worker 		case 3:
917*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
918*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
919*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
920*25da2beaSAndroid Build Coastguard Worker 				goto err;
921*25da2beaSAndroid Build Coastguard Worker 			}
922*25da2beaSAndroid Build Coastguard Worker 			break;
923*25da2beaSAndroid Build Coastguard Worker 		}
924*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
925*25da2beaSAndroid Build Coastguard Worker 	}
926*25da2beaSAndroid Build Coastguard Worker 
927*25da2beaSAndroid Build Coastguard Worker 	close(fds[0]);
928*25da2beaSAndroid Build Coastguard Worker 	close(fds[1]);
929*25da2beaSAndroid Build Coastguard Worker 	return 0;
930*25da2beaSAndroid Build Coastguard Worker err:
931*25da2beaSAndroid Build Coastguard Worker 	return 1;
932*25da2beaSAndroid Build Coastguard Worker }
933*25da2beaSAndroid Build Coastguard Worker 
test_timeout_link_chain5(struct io_uring * ring)934*25da2beaSAndroid Build Coastguard Worker static int test_timeout_link_chain5(struct io_uring *ring)
935*25da2beaSAndroid Build Coastguard Worker {
936*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts1, ts2;
937*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
938*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
939*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
940*25da2beaSAndroid Build Coastguard Worker 
941*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
942*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
943*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
944*25da2beaSAndroid Build Coastguard Worker 		goto err;
945*25da2beaSAndroid Build Coastguard Worker 	}
946*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
947*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
948*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
949*25da2beaSAndroid Build Coastguard Worker 
950*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
951*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
952*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
953*25da2beaSAndroid Build Coastguard Worker 		goto err;
954*25da2beaSAndroid Build Coastguard Worker 	}
955*25da2beaSAndroid Build Coastguard Worker 	ts1.tv_sec = 1;
956*25da2beaSAndroid Build Coastguard Worker 	ts1.tv_nsec = 0;
957*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts1, 0);
958*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
959*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
960*25da2beaSAndroid Build Coastguard Worker 
961*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
962*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
963*25da2beaSAndroid Build Coastguard Worker 		printf("get sqe failed\n");
964*25da2beaSAndroid Build Coastguard Worker 		goto err;
965*25da2beaSAndroid Build Coastguard Worker 	}
966*25da2beaSAndroid Build Coastguard Worker 	ts2.tv_sec = 2;
967*25da2beaSAndroid Build Coastguard Worker 	ts2.tv_nsec = 0;
968*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_link_timeout(sqe, &ts2, 0);
969*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
970*25da2beaSAndroid Build Coastguard Worker 
971*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
972*25da2beaSAndroid Build Coastguard Worker 	if (ret != 3) {
973*25da2beaSAndroid Build Coastguard Worker 		printf("sqe submit failed: %d\n", ret);
974*25da2beaSAndroid Build Coastguard Worker 		goto err;
975*25da2beaSAndroid Build Coastguard Worker 	}
976*25da2beaSAndroid Build Coastguard Worker 
977*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
978*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
979*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
980*25da2beaSAndroid Build Coastguard Worker 			printf("wait completion %d\n", ret);
981*25da2beaSAndroid Build Coastguard Worker 			goto err;
982*25da2beaSAndroid Build Coastguard Worker 		}
983*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
984*25da2beaSAndroid Build Coastguard Worker 		case 1:
985*25da2beaSAndroid Build Coastguard Worker 		case 2:
986*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res && cqe->res != -ECANCELED) {
987*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Request got %d, wanted -EINVAL "
988*25da2beaSAndroid Build Coastguard Worker 						"or -ECANCELED\n",
989*25da2beaSAndroid Build Coastguard Worker 						cqe->res);
990*25da2beaSAndroid Build Coastguard Worker 				goto err;
991*25da2beaSAndroid Build Coastguard Worker 			}
992*25da2beaSAndroid Build Coastguard Worker 			break;
993*25da2beaSAndroid Build Coastguard Worker 		case 3:
994*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED && cqe->res != -EINVAL) {
995*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "Link timeout got %d, wanted -ECANCELED\n", cqe->res);
996*25da2beaSAndroid Build Coastguard Worker 				goto err;
997*25da2beaSAndroid Build Coastguard Worker 			}
998*25da2beaSAndroid Build Coastguard Worker 			break;
999*25da2beaSAndroid Build Coastguard Worker 		}
1000*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
1001*25da2beaSAndroid Build Coastguard Worker 	}
1002*25da2beaSAndroid Build Coastguard Worker 
1003*25da2beaSAndroid Build Coastguard Worker 	return 0;
1004*25da2beaSAndroid Build Coastguard Worker err:
1005*25da2beaSAndroid Build Coastguard Worker 	return 1;
1006*25da2beaSAndroid Build Coastguard Worker }
1007*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])1008*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
1009*25da2beaSAndroid Build Coastguard Worker {
1010*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
1011*25da2beaSAndroid Build Coastguard Worker 	int ret;
1012*25da2beaSAndroid Build Coastguard Worker 
1013*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
1014*25da2beaSAndroid Build Coastguard Worker 		return 0;
1015*25da2beaSAndroid Build Coastguard Worker 
1016*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
1017*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1018*25da2beaSAndroid Build Coastguard Worker 		printf("ring setup failed\n");
1019*25da2beaSAndroid Build Coastguard Worker 		return 1;
1020*25da2beaSAndroid Build Coastguard Worker 	}
1021*25da2beaSAndroid Build Coastguard Worker 
1022*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_link_chain1(&ring);
1023*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1024*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_chain1 failed\n");
1025*25da2beaSAndroid Build Coastguard Worker 		return ret;
1026*25da2beaSAndroid Build Coastguard Worker 	}
1027*25da2beaSAndroid Build Coastguard Worker 
1028*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_link_chain2(&ring);
1029*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1030*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_chain2 failed\n");
1031*25da2beaSAndroid Build Coastguard Worker 		return ret;
1032*25da2beaSAndroid Build Coastguard Worker 	}
1033*25da2beaSAndroid Build Coastguard Worker 
1034*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_link_chain3(&ring);
1035*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1036*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_chain3 failed\n");
1037*25da2beaSAndroid Build Coastguard Worker 		return ret;
1038*25da2beaSAndroid Build Coastguard Worker 	}
1039*25da2beaSAndroid Build Coastguard Worker 
1040*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_link_chain4(&ring);
1041*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1042*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_chain4 failed\n");
1043*25da2beaSAndroid Build Coastguard Worker 		return ret;
1044*25da2beaSAndroid Build Coastguard Worker 	}
1045*25da2beaSAndroid Build Coastguard Worker 
1046*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_link_chain5(&ring);
1047*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1048*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_chain5 failed\n");
1049*25da2beaSAndroid Build Coastguard Worker 		return ret;
1050*25da2beaSAndroid Build Coastguard Worker 	}
1051*25da2beaSAndroid Build Coastguard Worker 
1052*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_timeout(&ring, 10);
1053*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1054*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_timeout 10 failed\n");
1055*25da2beaSAndroid Build Coastguard Worker 		return ret;
1056*25da2beaSAndroid Build Coastguard Worker 	}
1057*25da2beaSAndroid Build Coastguard Worker 
1058*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_timeout(&ring, 100000ULL);
1059*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1060*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_timeout 100000 failed\n");
1061*25da2beaSAndroid Build Coastguard Worker 		return ret;
1062*25da2beaSAndroid Build Coastguard Worker 	}
1063*25da2beaSAndroid Build Coastguard Worker 
1064*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_timeout(&ring, 500000000ULL);
1065*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1066*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_timeout 500000000 failed\n");
1067*25da2beaSAndroid Build Coastguard Worker 		return ret;
1068*25da2beaSAndroid Build Coastguard Worker 	}
1069*25da2beaSAndroid Build Coastguard Worker 
1070*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_no_timeout(&ring);
1071*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1072*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_no_timeout failed\n");
1073*25da2beaSAndroid Build Coastguard Worker 		return ret;
1074*25da2beaSAndroid Build Coastguard Worker 	}
1075*25da2beaSAndroid Build Coastguard Worker 
1076*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_timeout_error(&ring);
1077*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1078*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_timeout_error failed\n");
1079*25da2beaSAndroid Build Coastguard Worker 		return ret;
1080*25da2beaSAndroid Build Coastguard Worker 	}
1081*25da2beaSAndroid Build Coastguard Worker 
1082*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_timeout_nop(&ring);
1083*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1084*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_timeout_nop failed\n");
1085*25da2beaSAndroid Build Coastguard Worker 		return ret;
1086*25da2beaSAndroid Build Coastguard Worker 	}
1087*25da2beaSAndroid Build Coastguard Worker 
1088*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_link_timeout_ception(&ring);
1089*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1090*25da2beaSAndroid Build Coastguard Worker 		printf("test_single_link_timeout_ception failed\n");
1091*25da2beaSAndroid Build Coastguard Worker 		return ret;
1092*25da2beaSAndroid Build Coastguard Worker 	}
1093*25da2beaSAndroid Build Coastguard Worker 
1094*25da2beaSAndroid Build Coastguard Worker 	ret = test_fail_lone_link_timeouts(&ring);
1095*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1096*25da2beaSAndroid Build Coastguard Worker 		printf("test_fail_lone_link_timeouts failed\n");
1097*25da2beaSAndroid Build Coastguard Worker 		return ret;
1098*25da2beaSAndroid Build Coastguard Worker 	}
1099*25da2beaSAndroid Build Coastguard Worker 
1100*25da2beaSAndroid Build Coastguard Worker 	ret = test_fail_two_link_timeouts(&ring);
1101*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1102*25da2beaSAndroid Build Coastguard Worker 		printf("test_fail_two_link_timeouts failed\n");
1103*25da2beaSAndroid Build Coastguard Worker 		return ret;
1104*25da2beaSAndroid Build Coastguard Worker 	}
1105*25da2beaSAndroid Build Coastguard Worker 
1106*25da2beaSAndroid Build Coastguard Worker 	return 0;
1107*25da2beaSAndroid Build Coastguard Worker }
1108