xref: /aosp_15_r20/external/liburing/test/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 timeout tests
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 <sys/time.h>
13*25da2beaSAndroid Build Coastguard Worker #include <sys/wait.h>
14*25da2beaSAndroid Build Coastguard Worker #include <sys/types.h>
15*25da2beaSAndroid Build Coastguard Worker #include <sys/stat.h>
16*25da2beaSAndroid Build Coastguard Worker 
17*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
18*25da2beaSAndroid Build Coastguard Worker #include "../src/syscall.h"
19*25da2beaSAndroid Build Coastguard Worker 
20*25da2beaSAndroid Build Coastguard Worker #define TIMEOUT_MSEC	200
21*25da2beaSAndroid Build Coastguard Worker static int not_supported;
22*25da2beaSAndroid Build Coastguard Worker static int no_modify;
23*25da2beaSAndroid Build Coastguard Worker 
msec_to_ts(struct __kernel_timespec * ts,unsigned int msec)24*25da2beaSAndroid Build Coastguard Worker static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec)
25*25da2beaSAndroid Build Coastguard Worker {
26*25da2beaSAndroid Build Coastguard Worker 	ts->tv_sec = msec / 1000;
27*25da2beaSAndroid Build Coastguard Worker 	ts->tv_nsec = (msec % 1000) * 1000000;
28*25da2beaSAndroid Build Coastguard Worker }
29*25da2beaSAndroid Build Coastguard Worker 
mtime_since(const struct timeval * s,const struct timeval * e)30*25da2beaSAndroid Build Coastguard Worker static unsigned long long mtime_since(const struct timeval *s,
31*25da2beaSAndroid Build Coastguard Worker 				      const struct timeval *e)
32*25da2beaSAndroid Build Coastguard Worker {
33*25da2beaSAndroid Build Coastguard Worker 	long long sec, usec;
34*25da2beaSAndroid Build Coastguard Worker 
35*25da2beaSAndroid Build Coastguard Worker 	sec = e->tv_sec - s->tv_sec;
36*25da2beaSAndroid Build Coastguard Worker 	usec = (e->tv_usec - s->tv_usec);
37*25da2beaSAndroid Build Coastguard Worker 	if (sec > 0 && usec < 0) {
38*25da2beaSAndroid Build Coastguard Worker 		sec--;
39*25da2beaSAndroid Build Coastguard Worker 		usec += 1000000;
40*25da2beaSAndroid Build Coastguard Worker 	}
41*25da2beaSAndroid Build Coastguard Worker 
42*25da2beaSAndroid Build Coastguard Worker 	sec *= 1000;
43*25da2beaSAndroid Build Coastguard Worker 	usec /= 1000;
44*25da2beaSAndroid Build Coastguard Worker 	return sec + usec;
45*25da2beaSAndroid Build Coastguard Worker }
46*25da2beaSAndroid Build Coastguard Worker 
mtime_since_now(struct timeval * tv)47*25da2beaSAndroid Build Coastguard Worker static unsigned long long mtime_since_now(struct timeval *tv)
48*25da2beaSAndroid Build Coastguard Worker {
49*25da2beaSAndroid Build Coastguard Worker 	struct timeval end;
50*25da2beaSAndroid Build Coastguard Worker 
51*25da2beaSAndroid Build Coastguard Worker 	gettimeofday(&end, NULL);
52*25da2beaSAndroid Build Coastguard Worker 	return mtime_since(tv, &end);
53*25da2beaSAndroid Build Coastguard Worker }
54*25da2beaSAndroid Build Coastguard Worker 
55*25da2beaSAndroid Build Coastguard Worker /*
56*25da2beaSAndroid Build Coastguard Worker  * Test that we return to userspace if a timeout triggers, even if we
57*25da2beaSAndroid Build Coastguard Worker  * don't satisfy the number of events asked for.
58*25da2beaSAndroid Build Coastguard Worker  */
test_single_timeout_many(struct io_uring * ring)59*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_many(struct io_uring *ring)
60*25da2beaSAndroid Build Coastguard Worker {
61*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
62*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
63*25da2beaSAndroid Build Coastguard Worker 	unsigned long long exp;
64*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
65*25da2beaSAndroid Build Coastguard Worker 	struct timeval tv;
66*25da2beaSAndroid Build Coastguard Worker 	int ret;
67*25da2beaSAndroid Build Coastguard Worker 
68*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
69*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
70*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
71*25da2beaSAndroid Build Coastguard Worker 		goto err;
72*25da2beaSAndroid Build Coastguard Worker 	}
73*25da2beaSAndroid Build Coastguard Worker 
74*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
75*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
76*25da2beaSAndroid Build Coastguard Worker 
77*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
78*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
79*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
80*25da2beaSAndroid Build Coastguard Worker 		goto err;
81*25da2beaSAndroid Build Coastguard Worker 	}
82*25da2beaSAndroid Build Coastguard Worker 
83*25da2beaSAndroid Build Coastguard Worker 	gettimeofday(&tv, NULL);
84*25da2beaSAndroid Build Coastguard Worker 	ret = __sys_io_uring_enter(ring->ring_fd, 0, 4, IORING_ENTER_GETEVENTS,
85*25da2beaSAndroid Build Coastguard Worker 					NULL);
86*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
87*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: io_uring_enter %d\n", __FUNCTION__, ret);
88*25da2beaSAndroid Build Coastguard Worker 		goto err;
89*25da2beaSAndroid Build Coastguard Worker 	}
90*25da2beaSAndroid Build Coastguard Worker 
91*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
92*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
93*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
94*25da2beaSAndroid Build Coastguard Worker 		goto err;
95*25da2beaSAndroid Build Coastguard Worker 	}
96*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
97*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
98*25da2beaSAndroid Build Coastguard Worker 	if (ret == -EINVAL) {
99*25da2beaSAndroid Build Coastguard Worker 		fprintf(stdout, "Timeout not supported, ignored\n");
100*25da2beaSAndroid Build Coastguard Worker 		not_supported = 1;
101*25da2beaSAndroid Build Coastguard Worker 		return 0;
102*25da2beaSAndroid Build Coastguard Worker 	} else if (ret != -ETIME) {
103*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Timeout: %s\n", strerror(-ret));
104*25da2beaSAndroid Build Coastguard Worker 		goto err;
105*25da2beaSAndroid Build Coastguard Worker 	}
106*25da2beaSAndroid Build Coastguard Worker 
107*25da2beaSAndroid Build Coastguard Worker 	exp = mtime_since_now(&tv);
108*25da2beaSAndroid Build Coastguard Worker 	if (exp >= TIMEOUT_MSEC / 2 && exp <= (TIMEOUT_MSEC * 3) / 2)
109*25da2beaSAndroid Build Coastguard Worker 		return 0;
110*25da2beaSAndroid Build Coastguard Worker 	fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
111*25da2beaSAndroid Build Coastguard Worker err:
112*25da2beaSAndroid Build Coastguard Worker 	return 1;
113*25da2beaSAndroid Build Coastguard Worker }
114*25da2beaSAndroid Build Coastguard Worker 
115*25da2beaSAndroid Build Coastguard Worker /*
116*25da2beaSAndroid Build Coastguard Worker  * Test numbered trigger of timeout
117*25da2beaSAndroid Build Coastguard Worker  */
test_single_timeout_nr(struct io_uring * ring,int nr)118*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_nr(struct io_uring *ring, int nr)
119*25da2beaSAndroid Build Coastguard Worker {
120*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
121*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
122*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
123*25da2beaSAndroid Build Coastguard Worker 	int i, ret;
124*25da2beaSAndroid Build Coastguard Worker 
125*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
126*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
127*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
128*25da2beaSAndroid Build Coastguard Worker 		goto err;
129*25da2beaSAndroid Build Coastguard Worker 	}
130*25da2beaSAndroid Build Coastguard Worker 
131*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
132*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, nr, 0);
133*25da2beaSAndroid Build Coastguard Worker 
134*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
135*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
136*25da2beaSAndroid Build Coastguard Worker 	io_uring_sqe_set_data(sqe, (void *) 1);
137*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
138*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
139*25da2beaSAndroid Build Coastguard Worker 	io_uring_sqe_set_data(sqe, (void *) 1);
140*25da2beaSAndroid Build Coastguard Worker 
141*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit_and_wait(ring, 3);
142*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
143*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
144*25da2beaSAndroid Build Coastguard Worker 		goto err;
145*25da2beaSAndroid Build Coastguard Worker 	}
146*25da2beaSAndroid Build Coastguard Worker 
147*25da2beaSAndroid Build Coastguard Worker 	i = 0;
148*25da2beaSAndroid Build Coastguard Worker 	while (i < 3) {
149*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
150*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
151*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
152*25da2beaSAndroid Build Coastguard Worker 			goto err;
153*25da2beaSAndroid Build Coastguard Worker 		}
154*25da2beaSAndroid Build Coastguard Worker 
155*25da2beaSAndroid Build Coastguard Worker 		ret = cqe->res;
156*25da2beaSAndroid Build Coastguard Worker 
157*25da2beaSAndroid Build Coastguard Worker 		/*
158*25da2beaSAndroid Build Coastguard Worker 		 * NOP commands have user_data as 1. Check that we get the
159*25da2beaSAndroid Build Coastguard Worker 		 * at least 'nr' NOPs first, then the successfully removed timout.
160*25da2beaSAndroid Build Coastguard Worker 		 */
161*25da2beaSAndroid Build Coastguard Worker 		if (io_uring_cqe_get_data(cqe) == NULL) {
162*25da2beaSAndroid Build Coastguard Worker 			if (i < nr) {
163*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: timeout received too early\n", __FUNCTION__);
164*25da2beaSAndroid Build Coastguard Worker 				goto err;
165*25da2beaSAndroid Build Coastguard Worker 			}
166*25da2beaSAndroid Build Coastguard Worker 			if (ret) {
167*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: timeout triggered by passage of"
168*25da2beaSAndroid Build Coastguard Worker 					" time, not by events completed\n", __FUNCTION__);
169*25da2beaSAndroid Build Coastguard Worker 				goto err;
170*25da2beaSAndroid Build Coastguard Worker 			}
171*25da2beaSAndroid Build Coastguard Worker 		}
172*25da2beaSAndroid Build Coastguard Worker 
173*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
174*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
175*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "res: %d\n", ret);
176*25da2beaSAndroid Build Coastguard Worker 			goto err;
177*25da2beaSAndroid Build Coastguard Worker 		}
178*25da2beaSAndroid Build Coastguard Worker 		i++;
179*25da2beaSAndroid Build Coastguard Worker 	};
180*25da2beaSAndroid Build Coastguard Worker 
181*25da2beaSAndroid Build Coastguard Worker 	return 0;
182*25da2beaSAndroid Build Coastguard Worker err:
183*25da2beaSAndroid Build Coastguard Worker 	return 1;
184*25da2beaSAndroid Build Coastguard Worker }
185*25da2beaSAndroid Build Coastguard Worker 
test_single_timeout_wait(struct io_uring * ring,struct io_uring_params * p)186*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_wait(struct io_uring *ring,
187*25da2beaSAndroid Build Coastguard Worker 				    struct io_uring_params *p)
188*25da2beaSAndroid Build Coastguard Worker {
189*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
190*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
191*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
192*25da2beaSAndroid Build Coastguard Worker 	int i, ret;
193*25da2beaSAndroid Build Coastguard Worker 
194*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
195*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
196*25da2beaSAndroid Build Coastguard Worker 	io_uring_sqe_set_data(sqe, (void *) 1);
197*25da2beaSAndroid Build Coastguard Worker 
198*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
199*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
200*25da2beaSAndroid Build Coastguard Worker 	io_uring_sqe_set_data(sqe, (void *) 1);
201*25da2beaSAndroid Build Coastguard Worker 
202*25da2beaSAndroid Build Coastguard Worker 	/* no implied submit for newer kernels */
203*25da2beaSAndroid Build Coastguard Worker 	if (p->features & IORING_FEAT_EXT_ARG) {
204*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_submit(ring);
205*25da2beaSAndroid Build Coastguard Worker 		if (ret != 2) {
206*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: submit %d\n", __FUNCTION__, ret);
207*25da2beaSAndroid Build Coastguard Worker 			return 1;
208*25da2beaSAndroid Build Coastguard Worker 		}
209*25da2beaSAndroid Build Coastguard Worker 	}
210*25da2beaSAndroid Build Coastguard Worker 
211*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, 1000);
212*25da2beaSAndroid Build Coastguard Worker 
213*25da2beaSAndroid Build Coastguard Worker 	i = 0;
214*25da2beaSAndroid Build Coastguard Worker 	do {
215*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqes(ring, &cqe, 2, &ts, NULL);
216*25da2beaSAndroid Build Coastguard Worker 		if (ret == -ETIME)
217*25da2beaSAndroid Build Coastguard Worker 			break;
218*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
219*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait timeout failed: %d\n", __FUNCTION__, ret);
220*25da2beaSAndroid Build Coastguard Worker 			goto err;
221*25da2beaSAndroid Build Coastguard Worker 		}
222*25da2beaSAndroid Build Coastguard Worker 
223*25da2beaSAndroid Build Coastguard Worker 		ret = cqe->res;
224*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
225*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
226*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "res: %d\n", ret);
227*25da2beaSAndroid Build Coastguard Worker 			goto err;
228*25da2beaSAndroid Build Coastguard Worker 		}
229*25da2beaSAndroid Build Coastguard Worker 		i++;
230*25da2beaSAndroid Build Coastguard Worker 	} while (1);
231*25da2beaSAndroid Build Coastguard Worker 
232*25da2beaSAndroid Build Coastguard Worker 	if (i != 2) {
233*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "got %d completions\n", i);
234*25da2beaSAndroid Build Coastguard Worker 		goto err;
235*25da2beaSAndroid Build Coastguard Worker 	}
236*25da2beaSAndroid Build Coastguard Worker 	return 0;
237*25da2beaSAndroid Build Coastguard Worker err:
238*25da2beaSAndroid Build Coastguard Worker 	return 1;
239*25da2beaSAndroid Build Coastguard Worker }
240*25da2beaSAndroid Build Coastguard Worker 
241*25da2beaSAndroid Build Coastguard Worker /*
242*25da2beaSAndroid Build Coastguard Worker  * Test single timeout waking us up
243*25da2beaSAndroid Build Coastguard Worker  */
test_single_timeout(struct io_uring * ring)244*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout(struct io_uring *ring)
245*25da2beaSAndroid Build Coastguard Worker {
246*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
247*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
248*25da2beaSAndroid Build Coastguard Worker 	unsigned long long exp;
249*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
250*25da2beaSAndroid Build Coastguard Worker 	struct timeval tv;
251*25da2beaSAndroid Build Coastguard Worker 	int ret;
252*25da2beaSAndroid Build Coastguard Worker 
253*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
254*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
255*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
256*25da2beaSAndroid Build Coastguard Worker 		goto err;
257*25da2beaSAndroid Build Coastguard Worker 	}
258*25da2beaSAndroid Build Coastguard Worker 
259*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
260*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
261*25da2beaSAndroid Build Coastguard Worker 
262*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
263*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
264*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
265*25da2beaSAndroid Build Coastguard Worker 		goto err;
266*25da2beaSAndroid Build Coastguard Worker 	}
267*25da2beaSAndroid Build Coastguard Worker 
268*25da2beaSAndroid Build Coastguard Worker 	gettimeofday(&tv, NULL);
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 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
272*25da2beaSAndroid Build Coastguard Worker 		goto err;
273*25da2beaSAndroid Build Coastguard Worker 	}
274*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
275*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
276*25da2beaSAndroid Build Coastguard Worker 	if (ret == -EINVAL) {
277*25da2beaSAndroid Build Coastguard Worker 		fprintf(stdout, "%s: Timeout not supported, ignored\n", __FUNCTION__);
278*25da2beaSAndroid Build Coastguard Worker 		not_supported = 1;
279*25da2beaSAndroid Build Coastguard Worker 		return 0;
280*25da2beaSAndroid Build Coastguard Worker 	} else if (ret != -ETIME) {
281*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret));
282*25da2beaSAndroid Build Coastguard Worker 		goto err;
283*25da2beaSAndroid Build Coastguard Worker 	}
284*25da2beaSAndroid Build Coastguard Worker 
285*25da2beaSAndroid Build Coastguard Worker 	exp = mtime_since_now(&tv);
286*25da2beaSAndroid Build Coastguard Worker 	if (exp >= TIMEOUT_MSEC / 2 && exp <= (TIMEOUT_MSEC * 3) / 2)
287*25da2beaSAndroid Build Coastguard Worker 		return 0;
288*25da2beaSAndroid Build Coastguard Worker 	fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
289*25da2beaSAndroid Build Coastguard Worker err:
290*25da2beaSAndroid Build Coastguard Worker 	return 1;
291*25da2beaSAndroid Build Coastguard Worker }
292*25da2beaSAndroid Build Coastguard Worker 
test_single_timeout_remove_notfound(struct io_uring * ring)293*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_remove_notfound(struct io_uring *ring)
294*25da2beaSAndroid Build Coastguard Worker {
295*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
296*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
297*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
298*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
299*25da2beaSAndroid Build Coastguard Worker 
300*25da2beaSAndroid Build Coastguard Worker 	if (no_modify)
301*25da2beaSAndroid Build Coastguard Worker 		return 0;
302*25da2beaSAndroid Build Coastguard Worker 
303*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
304*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
305*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
306*25da2beaSAndroid Build Coastguard Worker 		goto err;
307*25da2beaSAndroid Build Coastguard Worker 	}
308*25da2beaSAndroid Build Coastguard Worker 
309*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
310*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 2, 0);
311*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
312*25da2beaSAndroid Build Coastguard Worker 
313*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
314*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
315*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
316*25da2beaSAndroid Build Coastguard Worker 		goto err;
317*25da2beaSAndroid Build Coastguard Worker 	}
318*25da2beaSAndroid Build Coastguard Worker 
319*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
320*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
321*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
322*25da2beaSAndroid Build Coastguard Worker 		goto err;
323*25da2beaSAndroid Build Coastguard Worker 	}
324*25da2beaSAndroid Build Coastguard Worker 
325*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout_remove(sqe, 2, 0);
326*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
327*25da2beaSAndroid Build Coastguard Worker 
328*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
329*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
330*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
331*25da2beaSAndroid Build Coastguard Worker 		goto err;
332*25da2beaSAndroid Build Coastguard Worker 	}
333*25da2beaSAndroid Build Coastguard Worker 
334*25da2beaSAndroid Build Coastguard Worker 	/*
335*25da2beaSAndroid Build Coastguard Worker 	 * We should get two completions. One is our modify request, which should
336*25da2beaSAndroid Build Coastguard Worker 	 * complete with -ENOENT. The other is the timeout that will trigger after
337*25da2beaSAndroid Build Coastguard Worker 	 * TIMEOUT_MSEC.
338*25da2beaSAndroid Build Coastguard Worker 	 */
339*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
340*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
341*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
342*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
343*25da2beaSAndroid Build Coastguard Worker 			goto err;
344*25da2beaSAndroid Build Coastguard Worker 		}
345*25da2beaSAndroid Build Coastguard Worker 		if (cqe->user_data == 2) {
346*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ENOENT) {
347*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: modify ret %d, wanted ENOENT\n", __FUNCTION__, cqe->res);
348*25da2beaSAndroid Build Coastguard Worker 				break;
349*25da2beaSAndroid Build Coastguard Worker 			}
350*25da2beaSAndroid Build Coastguard Worker 		} else if (cqe->user_data == 1) {
351*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
352*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: timeout ret %d, wanted -ETIME\n", __FUNCTION__, cqe->res);
353*25da2beaSAndroid Build Coastguard Worker 				break;
354*25da2beaSAndroid Build Coastguard Worker 			}
355*25da2beaSAndroid Build Coastguard Worker 		}
356*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
357*25da2beaSAndroid Build Coastguard Worker 	}
358*25da2beaSAndroid Build Coastguard Worker 	return 0;
359*25da2beaSAndroid Build Coastguard Worker err:
360*25da2beaSAndroid Build Coastguard Worker 	return 1;
361*25da2beaSAndroid Build Coastguard Worker }
362*25da2beaSAndroid Build Coastguard Worker 
test_single_timeout_remove(struct io_uring * ring)363*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_remove(struct io_uring *ring)
364*25da2beaSAndroid Build Coastguard Worker {
365*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
366*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
367*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
368*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
369*25da2beaSAndroid Build Coastguard Worker 
370*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
371*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
372*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
373*25da2beaSAndroid Build Coastguard Worker 		goto err;
374*25da2beaSAndroid Build Coastguard Worker 	}
375*25da2beaSAndroid Build Coastguard Worker 
376*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
377*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
378*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
379*25da2beaSAndroid Build Coastguard Worker 
380*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
381*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
382*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
383*25da2beaSAndroid Build Coastguard Worker 		goto err;
384*25da2beaSAndroid Build Coastguard Worker 	}
385*25da2beaSAndroid Build Coastguard Worker 
386*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
387*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
388*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
389*25da2beaSAndroid Build Coastguard Worker 		goto err;
390*25da2beaSAndroid Build Coastguard Worker 	}
391*25da2beaSAndroid Build Coastguard Worker 
392*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout_remove(sqe, 1, 0);
393*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
394*25da2beaSAndroid Build Coastguard Worker 
395*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
396*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
397*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
398*25da2beaSAndroid Build Coastguard Worker 		goto err;
399*25da2beaSAndroid Build Coastguard Worker 	}
400*25da2beaSAndroid Build Coastguard Worker 
401*25da2beaSAndroid Build Coastguard Worker 	/*
402*25da2beaSAndroid Build Coastguard Worker 	 * We should have two completions ready. One is for the original timeout
403*25da2beaSAndroid Build Coastguard Worker 	 * request, user_data == 1, that should have a ret of -ECANCELED. The other
404*25da2beaSAndroid Build Coastguard Worker 	 * is for our modify request, user_data == 2, that should have a ret of 0.
405*25da2beaSAndroid Build Coastguard Worker 	 */
406*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
407*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
408*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
409*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
410*25da2beaSAndroid Build Coastguard Worker 			goto err;
411*25da2beaSAndroid Build Coastguard Worker 		}
412*25da2beaSAndroid Build Coastguard Worker 		if (no_modify)
413*25da2beaSAndroid Build Coastguard Worker 			goto seen;
414*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res == -EINVAL && cqe->user_data == 2) {
415*25da2beaSAndroid Build Coastguard Worker 			fprintf(stdout, "Timeout modify not supported, ignoring\n");
416*25da2beaSAndroid Build Coastguard Worker 			no_modify = 1;
417*25da2beaSAndroid Build Coastguard Worker 			goto seen;
418*25da2beaSAndroid Build Coastguard Worker 		}
419*25da2beaSAndroid Build Coastguard Worker 		if (cqe->user_data == 1) {
420*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
421*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: timeout ret %d, wanted canceled\n", __FUNCTION__, cqe->res);
422*25da2beaSAndroid Build Coastguard Worker 				break;
423*25da2beaSAndroid Build Coastguard Worker 			}
424*25da2beaSAndroid Build Coastguard Worker 		} else if (cqe->user_data == 2) {
425*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res) {
426*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: modify ret %d, wanted 0\n", __FUNCTION__, cqe->res);
427*25da2beaSAndroid Build Coastguard Worker 				break;
428*25da2beaSAndroid Build Coastguard Worker 			}
429*25da2beaSAndroid Build Coastguard Worker 		}
430*25da2beaSAndroid Build Coastguard Worker seen:
431*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
432*25da2beaSAndroid Build Coastguard Worker 	}
433*25da2beaSAndroid Build Coastguard Worker 	return 0;
434*25da2beaSAndroid Build Coastguard Worker err:
435*25da2beaSAndroid Build Coastguard Worker 	return 1;
436*25da2beaSAndroid Build Coastguard Worker }
437*25da2beaSAndroid Build Coastguard Worker 
438*25da2beaSAndroid Build Coastguard Worker /*
439*25da2beaSAndroid Build Coastguard Worker  * Test single absolute timeout waking us up
440*25da2beaSAndroid Build Coastguard Worker  */
test_single_timeout_abs(struct io_uring * ring)441*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_abs(struct io_uring *ring)
442*25da2beaSAndroid Build Coastguard Worker {
443*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
444*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
445*25da2beaSAndroid Build Coastguard Worker 	unsigned long long exp;
446*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
447*25da2beaSAndroid Build Coastguard Worker 	struct timespec abs_ts;
448*25da2beaSAndroid Build Coastguard Worker 	struct timeval tv;
449*25da2beaSAndroid Build Coastguard Worker 	int ret;
450*25da2beaSAndroid Build Coastguard Worker 
451*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
452*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
453*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
454*25da2beaSAndroid Build Coastguard Worker 		goto err;
455*25da2beaSAndroid Build Coastguard Worker 	}
456*25da2beaSAndroid Build Coastguard Worker 
457*25da2beaSAndroid Build Coastguard Worker 	clock_gettime(CLOCK_MONOTONIC, &abs_ts);
458*25da2beaSAndroid Build Coastguard Worker 	ts.tv_sec = abs_ts.tv_sec + 1;
459*25da2beaSAndroid Build Coastguard Worker 	ts.tv_nsec = abs_ts.tv_nsec;
460*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_ABS);
461*25da2beaSAndroid Build Coastguard Worker 
462*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
463*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
464*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
465*25da2beaSAndroid Build Coastguard Worker 		goto err;
466*25da2beaSAndroid Build Coastguard Worker 	}
467*25da2beaSAndroid Build Coastguard Worker 
468*25da2beaSAndroid Build Coastguard Worker 	gettimeofday(&tv, NULL);
469*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
470*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
471*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
472*25da2beaSAndroid Build Coastguard Worker 		goto err;
473*25da2beaSAndroid Build Coastguard Worker 	}
474*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
475*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
476*25da2beaSAndroid Build Coastguard Worker 	if (ret == -EINVAL) {
477*25da2beaSAndroid Build Coastguard Worker 		fprintf(stdout, "Absolute timeouts not supported, ignored\n");
478*25da2beaSAndroid Build Coastguard Worker 		return 0;
479*25da2beaSAndroid Build Coastguard Worker 	} else if (ret != -ETIME) {
480*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Timeout: %s\n", strerror(-ret));
481*25da2beaSAndroid Build Coastguard Worker 		goto err;
482*25da2beaSAndroid Build Coastguard Worker 	}
483*25da2beaSAndroid Build Coastguard Worker 
484*25da2beaSAndroid Build Coastguard Worker 	exp = mtime_since_now(&tv);
485*25da2beaSAndroid Build Coastguard Worker 	if (exp >= 1000 / 2 && exp <= (1000 * 3) / 2)
486*25da2beaSAndroid Build Coastguard Worker 		return 0;
487*25da2beaSAndroid Build Coastguard Worker 	fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp);
488*25da2beaSAndroid Build Coastguard Worker err:
489*25da2beaSAndroid Build Coastguard Worker 	return 1;
490*25da2beaSAndroid Build Coastguard Worker }
491*25da2beaSAndroid Build Coastguard Worker 
492*25da2beaSAndroid Build Coastguard Worker /*
493*25da2beaSAndroid Build Coastguard Worker  * Test that timeout is canceled on exit
494*25da2beaSAndroid Build Coastguard Worker  */
test_single_timeout_exit(struct io_uring * ring)495*25da2beaSAndroid Build Coastguard Worker static int test_single_timeout_exit(struct io_uring *ring)
496*25da2beaSAndroid Build Coastguard Worker {
497*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
498*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
499*25da2beaSAndroid Build Coastguard Worker 	int ret;
500*25da2beaSAndroid Build Coastguard Worker 
501*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
502*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
503*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
504*25da2beaSAndroid Build Coastguard Worker 		goto err;
505*25da2beaSAndroid Build Coastguard Worker 	}
506*25da2beaSAndroid Build Coastguard Worker 
507*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, 30000);
508*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
509*25da2beaSAndroid Build Coastguard Worker 
510*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
511*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
512*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
513*25da2beaSAndroid Build Coastguard Worker 		goto err;
514*25da2beaSAndroid Build Coastguard Worker 	}
515*25da2beaSAndroid Build Coastguard Worker 
516*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(ring);
517*25da2beaSAndroid Build Coastguard Worker 	return 0;
518*25da2beaSAndroid Build Coastguard Worker err:
519*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(ring);
520*25da2beaSAndroid Build Coastguard Worker 	return 1;
521*25da2beaSAndroid Build Coastguard Worker }
522*25da2beaSAndroid Build Coastguard Worker 
523*25da2beaSAndroid Build Coastguard Worker /*
524*25da2beaSAndroid Build Coastguard Worker  * Test multi timeouts waking us up
525*25da2beaSAndroid Build Coastguard Worker  */
test_multi_timeout(struct io_uring * ring)526*25da2beaSAndroid Build Coastguard Worker static int test_multi_timeout(struct io_uring *ring)
527*25da2beaSAndroid Build Coastguard Worker {
528*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
529*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
530*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts[2];
531*25da2beaSAndroid Build Coastguard Worker 	unsigned int timeout[2];
532*25da2beaSAndroid Build Coastguard Worker 	unsigned long long exp;
533*25da2beaSAndroid Build Coastguard Worker 	struct timeval tv;
534*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
535*25da2beaSAndroid Build Coastguard Worker 
536*25da2beaSAndroid Build Coastguard Worker 	/* req_1: timeout req, count = 1, time = (TIMEOUT_MSEC * 2) */
537*25da2beaSAndroid Build Coastguard Worker 	timeout[0] = TIMEOUT_MSEC * 2;
538*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts[0], timeout[0]);
539*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
540*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
541*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
542*25da2beaSAndroid Build Coastguard Worker 		goto err;
543*25da2beaSAndroid Build Coastguard Worker 	}
544*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts[0], 1, 0);
545*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
546*25da2beaSAndroid Build Coastguard Worker 
547*25da2beaSAndroid Build Coastguard Worker 	/* req_2: timeout req, count = 1, time = TIMEOUT_MSEC */
548*25da2beaSAndroid Build Coastguard Worker 	timeout[1] = TIMEOUT_MSEC;
549*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts[1], timeout[1]);
550*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
551*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
552*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
553*25da2beaSAndroid Build Coastguard Worker 		goto err;
554*25da2beaSAndroid Build Coastguard Worker 	}
555*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts[1], 1, 0);
556*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
557*25da2beaSAndroid Build Coastguard Worker 
558*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
559*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
560*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
561*25da2beaSAndroid Build Coastguard Worker 		goto err;
562*25da2beaSAndroid Build Coastguard Worker 	}
563*25da2beaSAndroid Build Coastguard Worker 
564*25da2beaSAndroid Build Coastguard Worker 	gettimeofday(&tv, NULL);
565*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
566*25da2beaSAndroid Build Coastguard Worker 		unsigned int time = 0;
567*25da2beaSAndroid Build Coastguard Worker 		__u64 user_data = 0;
568*25da2beaSAndroid Build Coastguard Worker 
569*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
570*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
571*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
572*25da2beaSAndroid Build Coastguard Worker 			goto err;
573*25da2beaSAndroid Build Coastguard Worker 		}
574*25da2beaSAndroid Build Coastguard Worker 
575*25da2beaSAndroid Build Coastguard Worker 		/*
576*25da2beaSAndroid Build Coastguard Worker 		 * Both of these two reqs should timeout, but req_2 should
577*25da2beaSAndroid Build Coastguard Worker 		 * return before req_1.
578*25da2beaSAndroid Build Coastguard Worker 		 */
579*25da2beaSAndroid Build Coastguard Worker 		switch (i) {
580*25da2beaSAndroid Build Coastguard Worker 		case 0:
581*25da2beaSAndroid Build Coastguard Worker 			user_data = 2;
582*25da2beaSAndroid Build Coastguard Worker 			time = timeout[1];
583*25da2beaSAndroid Build Coastguard Worker 			break;
584*25da2beaSAndroid Build Coastguard Worker 		case 1:
585*25da2beaSAndroid Build Coastguard Worker 			user_data = 1;
586*25da2beaSAndroid Build Coastguard Worker 			time = timeout[0];
587*25da2beaSAndroid Build Coastguard Worker 			break;
588*25da2beaSAndroid Build Coastguard Worker 		}
589*25da2beaSAndroid Build Coastguard Worker 
590*25da2beaSAndroid Build Coastguard Worker 		if (cqe->user_data != user_data) {
591*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: unexpected timeout req %d sequece\n",
592*25da2beaSAndroid Build Coastguard Worker 				__FUNCTION__, i+1);
593*25da2beaSAndroid Build Coastguard Worker 			goto err;
594*25da2beaSAndroid Build Coastguard Worker 		}
595*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res != -ETIME) {
596*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: Req %d timeout: %s\n",
597*25da2beaSAndroid Build Coastguard Worker 				__FUNCTION__, i+1, strerror(cqe->res));
598*25da2beaSAndroid Build Coastguard Worker 			goto err;
599*25da2beaSAndroid Build Coastguard Worker 		}
600*25da2beaSAndroid Build Coastguard Worker 		exp = mtime_since_now(&tv);
601*25da2beaSAndroid Build Coastguard Worker 		if (exp < time / 2 || exp > (time * 3) / 2) {
602*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: Req %d timeout seems wonky (got %llu)\n",
603*25da2beaSAndroid Build Coastguard Worker 				__FUNCTION__, i+1, exp);
604*25da2beaSAndroid Build Coastguard Worker 			goto err;
605*25da2beaSAndroid Build Coastguard Worker 		}
606*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
607*25da2beaSAndroid Build Coastguard Worker 	}
608*25da2beaSAndroid Build Coastguard Worker 
609*25da2beaSAndroid Build Coastguard Worker 	return 0;
610*25da2beaSAndroid Build Coastguard Worker err:
611*25da2beaSAndroid Build Coastguard Worker 	return 1;
612*25da2beaSAndroid Build Coastguard Worker }
613*25da2beaSAndroid Build Coastguard Worker 
614*25da2beaSAndroid Build Coastguard Worker /*
615*25da2beaSAndroid Build Coastguard Worker  * Test multi timeout req with different count
616*25da2beaSAndroid Build Coastguard Worker  */
test_multi_timeout_nr(struct io_uring * ring)617*25da2beaSAndroid Build Coastguard Worker static int test_multi_timeout_nr(struct io_uring *ring)
618*25da2beaSAndroid Build Coastguard Worker {
619*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
620*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
621*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
622*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
623*25da2beaSAndroid Build Coastguard Worker 
624*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
625*25da2beaSAndroid Build Coastguard Worker 
626*25da2beaSAndroid Build Coastguard Worker 	/* req_1: timeout req, count = 2 */
627*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
628*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
629*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
630*25da2beaSAndroid Build Coastguard Worker 		goto err;
631*25da2beaSAndroid Build Coastguard Worker 	}
632*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 2, 0);
633*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
634*25da2beaSAndroid Build Coastguard Worker 
635*25da2beaSAndroid Build Coastguard Worker 	/* req_2: timeout req, count = 1 */
636*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
637*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
638*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
639*25da2beaSAndroid Build Coastguard Worker 		goto err;
640*25da2beaSAndroid Build Coastguard Worker 	}
641*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 1, 0);
642*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
643*25da2beaSAndroid Build Coastguard Worker 
644*25da2beaSAndroid Build Coastguard Worker 	/* req_3: nop req */
645*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
646*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
647*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
648*25da2beaSAndroid Build Coastguard Worker 		goto err;
649*25da2beaSAndroid Build Coastguard Worker 	}
650*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
651*25da2beaSAndroid Build Coastguard Worker 	io_uring_sqe_set_data(sqe, (void *) 1);
652*25da2beaSAndroid Build Coastguard Worker 
653*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
654*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
655*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
656*25da2beaSAndroid Build Coastguard Worker 		goto err;
657*25da2beaSAndroid Build Coastguard Worker 	}
658*25da2beaSAndroid Build Coastguard Worker 
659*25da2beaSAndroid Build Coastguard Worker 	/*
660*25da2beaSAndroid Build Coastguard Worker 	 * req_2 (count=1) should return without error and req_1 (count=2)
661*25da2beaSAndroid Build Coastguard Worker 	 * should timeout.
662*25da2beaSAndroid Build Coastguard Worker 	 */
663*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
664*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
665*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
666*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
667*25da2beaSAndroid Build Coastguard Worker 			goto err;
668*25da2beaSAndroid Build Coastguard Worker 		}
669*25da2beaSAndroid Build Coastguard Worker 
670*25da2beaSAndroid Build Coastguard Worker 		switch (i) {
671*25da2beaSAndroid Build Coastguard Worker 		case 0:
672*25da2beaSAndroid Build Coastguard Worker 			/* Should be nop req */
673*25da2beaSAndroid Build Coastguard Worker 			if (io_uring_cqe_get_data(cqe) != (void *) 1) {
674*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: nop not seen as 1 or 2\n", __FUNCTION__);
675*25da2beaSAndroid Build Coastguard Worker 				goto err;
676*25da2beaSAndroid Build Coastguard Worker 			}
677*25da2beaSAndroid Build Coastguard Worker 			break;
678*25da2beaSAndroid Build Coastguard Worker 		case 1:
679*25da2beaSAndroid Build Coastguard Worker 			/* Should be timeout req_2 */
680*25da2beaSAndroid Build Coastguard Worker 			if (cqe->user_data != 2) {
681*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: unexpected timeout req %d sequece\n",
682*25da2beaSAndroid Build Coastguard Worker 					__FUNCTION__, i+1);
683*25da2beaSAndroid Build Coastguard Worker 				goto err;
684*25da2beaSAndroid Build Coastguard Worker 			}
685*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res < 0) {
686*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: Req %d res %d\n",
687*25da2beaSAndroid Build Coastguard Worker 					__FUNCTION__, i+1, cqe->res);
688*25da2beaSAndroid Build Coastguard Worker 				goto err;
689*25da2beaSAndroid Build Coastguard Worker 			}
690*25da2beaSAndroid Build Coastguard Worker 			break;
691*25da2beaSAndroid Build Coastguard Worker 		case 2:
692*25da2beaSAndroid Build Coastguard Worker 			/* Should be timeout req_1 */
693*25da2beaSAndroid Build Coastguard Worker 			if (cqe->user_data != 1) {
694*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: unexpected timeout req %d sequece\n",
695*25da2beaSAndroid Build Coastguard Worker 					__FUNCTION__, i+1);
696*25da2beaSAndroid Build Coastguard Worker 				goto err;
697*25da2beaSAndroid Build Coastguard Worker 			}
698*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
699*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: Req %d timeout: %s\n",
700*25da2beaSAndroid Build Coastguard Worker 					__FUNCTION__, i+1, strerror(cqe->res));
701*25da2beaSAndroid Build Coastguard Worker 				goto err;
702*25da2beaSAndroid Build Coastguard Worker 			}
703*25da2beaSAndroid Build Coastguard Worker 			break;
704*25da2beaSAndroid Build Coastguard Worker 		}
705*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
706*25da2beaSAndroid Build Coastguard Worker 	}
707*25da2beaSAndroid Build Coastguard Worker 
708*25da2beaSAndroid Build Coastguard Worker 	return 0;
709*25da2beaSAndroid Build Coastguard Worker err:
710*25da2beaSAndroid Build Coastguard Worker 	return 1;
711*25da2beaSAndroid Build Coastguard Worker }
712*25da2beaSAndroid Build Coastguard Worker 
713*25da2beaSAndroid Build Coastguard Worker /*
714*25da2beaSAndroid Build Coastguard Worker  * Test timeout <link> timeout <drain> timeout
715*25da2beaSAndroid Build Coastguard Worker  */
test_timeout_flags1(struct io_uring * ring)716*25da2beaSAndroid Build Coastguard Worker static int test_timeout_flags1(struct io_uring *ring)
717*25da2beaSAndroid Build Coastguard Worker {
718*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
719*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
720*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
721*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
722*25da2beaSAndroid Build Coastguard Worker 
723*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
724*25da2beaSAndroid Build Coastguard Worker 
725*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
726*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
727*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
728*25da2beaSAndroid Build Coastguard Worker 		goto err;
729*25da2beaSAndroid Build Coastguard Worker 	}
730*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
731*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
732*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
733*25da2beaSAndroid Build Coastguard Worker 
734*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
735*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
736*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
737*25da2beaSAndroid Build Coastguard Worker 		goto err;
738*25da2beaSAndroid Build Coastguard Worker 	}
739*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
740*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
741*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_DRAIN;
742*25da2beaSAndroid Build Coastguard Worker 
743*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
744*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
745*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
746*25da2beaSAndroid Build Coastguard Worker 		goto err;
747*25da2beaSAndroid Build Coastguard Worker 	}
748*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
749*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
750*25da2beaSAndroid Build Coastguard Worker 
751*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
752*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
753*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
754*25da2beaSAndroid Build Coastguard Worker 		goto err;
755*25da2beaSAndroid Build Coastguard Worker 	}
756*25da2beaSAndroid Build Coastguard Worker 
757*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
758*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
759*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
760*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
761*25da2beaSAndroid Build Coastguard Worker 			goto err;
762*25da2beaSAndroid Build Coastguard Worker 		}
763*25da2beaSAndroid Build Coastguard Worker 
764*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res == -EINVAL) {
765*25da2beaSAndroid Build Coastguard Worker 			if (!i)
766*25da2beaSAndroid Build Coastguard Worker 				fprintf(stdout, "%s: timeout flags not supported\n",
767*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__);
768*25da2beaSAndroid Build Coastguard Worker 			io_uring_cqe_seen(ring, cqe);
769*25da2beaSAndroid Build Coastguard Worker 			continue;
770*25da2beaSAndroid Build Coastguard Worker 		}
771*25da2beaSAndroid Build Coastguard Worker 
772*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
773*25da2beaSAndroid Build Coastguard Worker 		case 1:
774*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
775*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
776*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res, -ETIME);
777*25da2beaSAndroid Build Coastguard Worker 				goto err;
778*25da2beaSAndroid Build Coastguard Worker 			}
779*25da2beaSAndroid Build Coastguard Worker 			break;
780*25da2beaSAndroid Build Coastguard Worker 		case 2:
781*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
782*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
783*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res,
784*25da2beaSAndroid Build Coastguard Worker 						-ECANCELED);
785*25da2beaSAndroid Build Coastguard Worker 				goto err;
786*25da2beaSAndroid Build Coastguard Worker 			}
787*25da2beaSAndroid Build Coastguard Worker 			break;
788*25da2beaSAndroid Build Coastguard Worker 		case 3:
789*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
790*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
791*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res, -ETIME);
792*25da2beaSAndroid Build Coastguard Worker 				goto err;
793*25da2beaSAndroid Build Coastguard Worker 			}
794*25da2beaSAndroid Build Coastguard Worker 			break;
795*25da2beaSAndroid Build Coastguard Worker 		}
796*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
797*25da2beaSAndroid Build Coastguard Worker 	}
798*25da2beaSAndroid Build Coastguard Worker 
799*25da2beaSAndroid Build Coastguard Worker 	return 0;
800*25da2beaSAndroid Build Coastguard Worker err:
801*25da2beaSAndroid Build Coastguard Worker 	return 1;
802*25da2beaSAndroid Build Coastguard Worker }
803*25da2beaSAndroid Build Coastguard Worker 
804*25da2beaSAndroid Build Coastguard Worker /*
805*25da2beaSAndroid Build Coastguard Worker  * Test timeout <link> timeout <link> timeout
806*25da2beaSAndroid Build Coastguard Worker  */
test_timeout_flags2(struct io_uring * ring)807*25da2beaSAndroid Build Coastguard Worker static int test_timeout_flags2(struct io_uring *ring)
808*25da2beaSAndroid Build Coastguard Worker {
809*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
810*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
811*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
812*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
813*25da2beaSAndroid Build Coastguard Worker 
814*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
815*25da2beaSAndroid Build Coastguard Worker 
816*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
817*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
818*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
819*25da2beaSAndroid Build Coastguard Worker 		goto err;
820*25da2beaSAndroid Build Coastguard Worker 	}
821*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
822*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
823*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
824*25da2beaSAndroid Build Coastguard Worker 
825*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
826*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
827*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
828*25da2beaSAndroid Build Coastguard Worker 		goto err;
829*25da2beaSAndroid Build Coastguard Worker 	}
830*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
831*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
832*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
833*25da2beaSAndroid Build Coastguard Worker 
834*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
835*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
836*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
837*25da2beaSAndroid Build Coastguard Worker 		goto err;
838*25da2beaSAndroid Build Coastguard Worker 	}
839*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
840*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
841*25da2beaSAndroid Build Coastguard Worker 
842*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
843*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
844*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
845*25da2beaSAndroid Build Coastguard Worker 		goto err;
846*25da2beaSAndroid Build Coastguard Worker 	}
847*25da2beaSAndroid Build Coastguard Worker 
848*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
849*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
850*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
851*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
852*25da2beaSAndroid Build Coastguard Worker 			goto err;
853*25da2beaSAndroid Build Coastguard Worker 		}
854*25da2beaSAndroid Build Coastguard Worker 
855*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res == -EINVAL) {
856*25da2beaSAndroid Build Coastguard Worker 			if (!i)
857*25da2beaSAndroid Build Coastguard Worker 				fprintf(stdout, "%s: timeout flags not supported\n",
858*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__);
859*25da2beaSAndroid Build Coastguard Worker 			io_uring_cqe_seen(ring, cqe);
860*25da2beaSAndroid Build Coastguard Worker 			continue;
861*25da2beaSAndroid Build Coastguard Worker 		}
862*25da2beaSAndroid Build Coastguard Worker 
863*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
864*25da2beaSAndroid Build Coastguard Worker 		case 1:
865*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
866*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
867*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res, -ETIME);
868*25da2beaSAndroid Build Coastguard Worker 				goto err;
869*25da2beaSAndroid Build Coastguard Worker 			}
870*25da2beaSAndroid Build Coastguard Worker 			break;
871*25da2beaSAndroid Build Coastguard Worker 		case 2:
872*25da2beaSAndroid Build Coastguard Worker 		case 3:
873*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
874*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
875*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res,
876*25da2beaSAndroid Build Coastguard Worker 						-ECANCELED);
877*25da2beaSAndroid Build Coastguard Worker 				goto err;
878*25da2beaSAndroid Build Coastguard Worker 			}
879*25da2beaSAndroid Build Coastguard Worker 			break;
880*25da2beaSAndroid Build Coastguard Worker 		}
881*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
882*25da2beaSAndroid Build Coastguard Worker 	}
883*25da2beaSAndroid Build Coastguard Worker 
884*25da2beaSAndroid Build Coastguard Worker 	return 0;
885*25da2beaSAndroid Build Coastguard Worker err:
886*25da2beaSAndroid Build Coastguard Worker 	return 1;
887*25da2beaSAndroid Build Coastguard Worker }
888*25da2beaSAndroid Build Coastguard Worker 
889*25da2beaSAndroid Build Coastguard Worker /*
890*25da2beaSAndroid Build Coastguard Worker  * Test timeout <drain> timeout <link> timeout
891*25da2beaSAndroid Build Coastguard Worker  */
test_timeout_flags3(struct io_uring * ring)892*25da2beaSAndroid Build Coastguard Worker static int test_timeout_flags3(struct io_uring *ring)
893*25da2beaSAndroid Build Coastguard Worker {
894*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
895*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
896*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
897*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
898*25da2beaSAndroid Build Coastguard Worker 
899*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, TIMEOUT_MSEC);
900*25da2beaSAndroid Build Coastguard Worker 
901*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
902*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
903*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
904*25da2beaSAndroid Build Coastguard Worker 		goto err;
905*25da2beaSAndroid Build Coastguard Worker 	}
906*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
907*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
908*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_DRAIN;
909*25da2beaSAndroid Build Coastguard Worker 
910*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
911*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
912*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
913*25da2beaSAndroid Build Coastguard Worker 		goto err;
914*25da2beaSAndroid Build Coastguard Worker 	}
915*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
916*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
917*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
918*25da2beaSAndroid Build Coastguard Worker 
919*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
920*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
921*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
922*25da2beaSAndroid Build Coastguard Worker 		goto err;
923*25da2beaSAndroid Build Coastguard Worker 	}
924*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
925*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 3;
926*25da2beaSAndroid Build Coastguard Worker 
927*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
928*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
929*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
930*25da2beaSAndroid Build Coastguard Worker 		goto err;
931*25da2beaSAndroid Build Coastguard Worker 	}
932*25da2beaSAndroid Build Coastguard Worker 
933*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 3; i++) {
934*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
935*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
936*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
937*25da2beaSAndroid Build Coastguard Worker 			goto err;
938*25da2beaSAndroid Build Coastguard Worker 		}
939*25da2beaSAndroid Build Coastguard Worker 
940*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res == -EINVAL) {
941*25da2beaSAndroid Build Coastguard Worker 			if (!i)
942*25da2beaSAndroid Build Coastguard Worker 				fprintf(stdout, "%s: timeout flags not supported\n",
943*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__);
944*25da2beaSAndroid Build Coastguard Worker 			io_uring_cqe_seen(ring, cqe);
945*25da2beaSAndroid Build Coastguard Worker 			continue;
946*25da2beaSAndroid Build Coastguard Worker 		}
947*25da2beaSAndroid Build Coastguard Worker 
948*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
949*25da2beaSAndroid Build Coastguard Worker 		case 1:
950*25da2beaSAndroid Build Coastguard Worker 		case 2:
951*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
952*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
953*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res, -ETIME);
954*25da2beaSAndroid Build Coastguard Worker 				goto err;
955*25da2beaSAndroid Build Coastguard Worker 			}
956*25da2beaSAndroid Build Coastguard Worker 			break;
957*25da2beaSAndroid Build Coastguard Worker 		case 3:
958*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ECANCELED) {
959*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
960*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res,
961*25da2beaSAndroid Build Coastguard Worker 						-ECANCELED);
962*25da2beaSAndroid Build Coastguard Worker 				goto err;
963*25da2beaSAndroid Build Coastguard Worker 			}
964*25da2beaSAndroid Build Coastguard Worker 			break;
965*25da2beaSAndroid Build Coastguard Worker 		}
966*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
967*25da2beaSAndroid Build Coastguard Worker 	}
968*25da2beaSAndroid Build Coastguard Worker 
969*25da2beaSAndroid Build Coastguard Worker 	return 0;
970*25da2beaSAndroid Build Coastguard Worker err:
971*25da2beaSAndroid Build Coastguard Worker 	return 1;
972*25da2beaSAndroid Build Coastguard Worker }
973*25da2beaSAndroid Build Coastguard Worker 
test_update_timeout(struct io_uring * ring,unsigned long ms,bool abs,bool async,bool linked)974*25da2beaSAndroid Build Coastguard Worker static int test_update_timeout(struct io_uring *ring, unsigned long ms,
975*25da2beaSAndroid Build Coastguard Worker 				bool abs, bool async, bool linked)
976*25da2beaSAndroid Build Coastguard Worker {
977*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
978*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
979*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts, ts_upd;
980*25da2beaSAndroid Build Coastguard Worker 	unsigned long long exp_ms, base_ms = 10000;
981*25da2beaSAndroid Build Coastguard Worker 	struct timeval tv;
982*25da2beaSAndroid Build Coastguard Worker 	int ret, i, nr = 2;
983*25da2beaSAndroid Build Coastguard Worker 	__u32 mode = abs ? IORING_TIMEOUT_ABS : 0;
984*25da2beaSAndroid Build Coastguard Worker 
985*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts_upd, ms);
986*25da2beaSAndroid Build Coastguard Worker 	gettimeofday(&tv, NULL);
987*25da2beaSAndroid Build Coastguard Worker 
988*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
989*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
990*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
991*25da2beaSAndroid Build Coastguard Worker 		goto err;
992*25da2beaSAndroid Build Coastguard Worker 	}
993*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, base_ms);
994*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, 0);
995*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
996*25da2beaSAndroid Build Coastguard Worker 
997*25da2beaSAndroid Build Coastguard Worker 	if (linked) {
998*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(ring);
999*25da2beaSAndroid Build Coastguard Worker 		if (!sqe) {
1000*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
1001*25da2beaSAndroid Build Coastguard Worker 			goto err;
1002*25da2beaSAndroid Build Coastguard Worker 		}
1003*25da2beaSAndroid Build Coastguard Worker 		io_uring_prep_nop(sqe);
1004*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = 3;
1005*25da2beaSAndroid Build Coastguard Worker 		sqe->flags = IOSQE_IO_LINK;
1006*25da2beaSAndroid Build Coastguard Worker 		if (async)
1007*25da2beaSAndroid Build Coastguard Worker 			sqe->flags |= IOSQE_ASYNC;
1008*25da2beaSAndroid Build Coastguard Worker 		nr++;
1009*25da2beaSAndroid Build Coastguard Worker 	}
1010*25da2beaSAndroid Build Coastguard Worker 
1011*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
1012*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
1013*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
1014*25da2beaSAndroid Build Coastguard Worker 		goto err;
1015*25da2beaSAndroid Build Coastguard Worker 	}
1016*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout_update(sqe, &ts_upd, 1, mode);
1017*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
1018*25da2beaSAndroid Build Coastguard Worker 	if (async)
1019*25da2beaSAndroid Build Coastguard Worker 		sqe->flags |= IOSQE_ASYNC;
1020*25da2beaSAndroid Build Coastguard Worker 
1021*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
1022*25da2beaSAndroid Build Coastguard Worker 	if (ret != nr) {
1023*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
1024*25da2beaSAndroid Build Coastguard Worker 		goto err;
1025*25da2beaSAndroid Build Coastguard Worker 	}
1026*25da2beaSAndroid Build Coastguard Worker 
1027*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < nr; i++) {
1028*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
1029*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
1030*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
1031*25da2beaSAndroid Build Coastguard Worker 			goto err;
1032*25da2beaSAndroid Build Coastguard Worker 		}
1033*25da2beaSAndroid Build Coastguard Worker 
1034*25da2beaSAndroid Build Coastguard Worker 		switch (cqe->user_data) {
1035*25da2beaSAndroid Build Coastguard Worker 		case 1:
1036*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != -ETIME) {
1037*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
1038*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res, -ETIME);
1039*25da2beaSAndroid Build Coastguard Worker 				goto err;
1040*25da2beaSAndroid Build Coastguard Worker 			}
1041*25da2beaSAndroid Build Coastguard Worker 			break;
1042*25da2beaSAndroid Build Coastguard Worker 		case 2:
1043*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 0) {
1044*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "%s: got %d, wanted %d\n",
1045*25da2beaSAndroid Build Coastguard Worker 						__FUNCTION__, cqe->res,
1046*25da2beaSAndroid Build Coastguard Worker 						0);
1047*25da2beaSAndroid Build Coastguard Worker 				goto err;
1048*25da2beaSAndroid Build Coastguard Worker 			}
1049*25da2beaSAndroid Build Coastguard Worker 			break;
1050*25da2beaSAndroid Build Coastguard Worker 		case 3:
1051*25da2beaSAndroid Build Coastguard Worker 			if (cqe->res != 0) {
1052*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "nop failed\n");
1053*25da2beaSAndroid Build Coastguard Worker 				goto err;
1054*25da2beaSAndroid Build Coastguard Worker 			}
1055*25da2beaSAndroid Build Coastguard Worker 			break;
1056*25da2beaSAndroid Build Coastguard Worker 		default:
1057*25da2beaSAndroid Build Coastguard Worker 			goto err;
1058*25da2beaSAndroid Build Coastguard Worker 		}
1059*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
1060*25da2beaSAndroid Build Coastguard Worker 	}
1061*25da2beaSAndroid Build Coastguard Worker 
1062*25da2beaSAndroid Build Coastguard Worker 	exp_ms = mtime_since_now(&tv);
1063*25da2beaSAndroid Build Coastguard Worker 	if (exp_ms >= base_ms / 2) {
1064*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "too long, timeout wasn't updated\n");
1065*25da2beaSAndroid Build Coastguard Worker 		goto err;
1066*25da2beaSAndroid Build Coastguard Worker 	}
1067*25da2beaSAndroid Build Coastguard Worker 	if (ms >= 1000 && !abs && exp_ms < ms / 2) {
1068*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "fired too early, potentially updated to 0 ms"
1069*25da2beaSAndroid Build Coastguard Worker 					"instead of %lu\n", ms);
1070*25da2beaSAndroid Build Coastguard Worker 		goto err;
1071*25da2beaSAndroid Build Coastguard Worker 	}
1072*25da2beaSAndroid Build Coastguard Worker 	return 0;
1073*25da2beaSAndroid Build Coastguard Worker err:
1074*25da2beaSAndroid Build Coastguard Worker 	return 1;
1075*25da2beaSAndroid Build Coastguard Worker }
1076*25da2beaSAndroid Build Coastguard Worker 
test_update_nonexistent_timeout(struct io_uring * ring)1077*25da2beaSAndroid Build Coastguard Worker static int test_update_nonexistent_timeout(struct io_uring *ring)
1078*25da2beaSAndroid Build Coastguard Worker {
1079*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
1080*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
1081*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
1082*25da2beaSAndroid Build Coastguard Worker 	int ret;
1083*25da2beaSAndroid Build Coastguard Worker 
1084*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
1085*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
1086*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
1087*25da2beaSAndroid Build Coastguard Worker 		goto err;
1088*25da2beaSAndroid Build Coastguard Worker 	}
1089*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, 0);
1090*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout_update(sqe, &ts, 42, 0);
1091*25da2beaSAndroid Build Coastguard Worker 
1092*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
1093*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
1094*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
1095*25da2beaSAndroid Build Coastguard Worker 		goto err;
1096*25da2beaSAndroid Build Coastguard Worker 	}
1097*25da2beaSAndroid Build Coastguard Worker 
1098*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
1099*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
1100*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
1101*25da2beaSAndroid Build Coastguard Worker 		goto err;
1102*25da2beaSAndroid Build Coastguard Worker 	}
1103*25da2beaSAndroid Build Coastguard Worker 
1104*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
1105*25da2beaSAndroid Build Coastguard Worker 	if (ret == -ENOENT)
1106*25da2beaSAndroid Build Coastguard Worker 		ret = 0;
1107*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
1108*25da2beaSAndroid Build Coastguard Worker 	return ret;
1109*25da2beaSAndroid Build Coastguard Worker err:
1110*25da2beaSAndroid Build Coastguard Worker 	return 1;
1111*25da2beaSAndroid Build Coastguard Worker }
1112*25da2beaSAndroid Build Coastguard Worker 
test_update_invalid_flags(struct io_uring * ring)1113*25da2beaSAndroid Build Coastguard Worker static int test_update_invalid_flags(struct io_uring *ring)
1114*25da2beaSAndroid Build Coastguard Worker {
1115*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
1116*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
1117*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
1118*25da2beaSAndroid Build Coastguard Worker 	int ret;
1119*25da2beaSAndroid Build Coastguard Worker 
1120*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
1121*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
1122*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
1123*25da2beaSAndroid Build Coastguard Worker 		goto err;
1124*25da2beaSAndroid Build Coastguard Worker 	}
1125*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout_remove(sqe, 0, IORING_TIMEOUT_ABS);
1126*25da2beaSAndroid Build Coastguard Worker 
1127*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
1128*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
1129*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
1130*25da2beaSAndroid Build Coastguard Worker 		goto err;
1131*25da2beaSAndroid Build Coastguard Worker 	}
1132*25da2beaSAndroid Build Coastguard Worker 
1133*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
1134*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
1135*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
1136*25da2beaSAndroid Build Coastguard Worker 		goto err;
1137*25da2beaSAndroid Build Coastguard Worker 	}
1138*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res != -EINVAL) {
1139*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: got %d, wanted %d\n",
1140*25da2beaSAndroid Build Coastguard Worker 				__FUNCTION__, cqe->res, -EINVAL);
1141*25da2beaSAndroid Build Coastguard Worker 		goto err;
1142*25da2beaSAndroid Build Coastguard Worker 	}
1143*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
1144*25da2beaSAndroid Build Coastguard Worker 
1145*25da2beaSAndroid Build Coastguard Worker 
1146*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
1147*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
1148*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__);
1149*25da2beaSAndroid Build Coastguard Worker 		goto err;
1150*25da2beaSAndroid Build Coastguard Worker 	}
1151*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, 0);
1152*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout_update(sqe, &ts, 0, -1);
1153*25da2beaSAndroid Build Coastguard Worker 
1154*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
1155*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
1156*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
1157*25da2beaSAndroid Build Coastguard Worker 		goto err;
1158*25da2beaSAndroid Build Coastguard Worker 	}
1159*25da2beaSAndroid Build Coastguard Worker 
1160*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
1161*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
1162*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
1163*25da2beaSAndroid Build Coastguard Worker 		goto err;
1164*25da2beaSAndroid Build Coastguard Worker 	}
1165*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res != -EINVAL) {
1166*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: got %d, wanted %d\n",
1167*25da2beaSAndroid Build Coastguard Worker 				__FUNCTION__, cqe->res, -EINVAL);
1168*25da2beaSAndroid Build Coastguard Worker 		goto err;
1169*25da2beaSAndroid Build Coastguard Worker 	}
1170*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
1171*25da2beaSAndroid Build Coastguard Worker 
1172*25da2beaSAndroid Build Coastguard Worker 	return 0;
1173*25da2beaSAndroid Build Coastguard Worker err:
1174*25da2beaSAndroid Build Coastguard Worker 	return 1;
1175*25da2beaSAndroid Build Coastguard Worker }
1176*25da2beaSAndroid Build Coastguard Worker 
fill_exec_target(char * dst,char * path)1177*25da2beaSAndroid Build Coastguard Worker static int fill_exec_target(char *dst, char *path)
1178*25da2beaSAndroid Build Coastguard Worker {
1179*25da2beaSAndroid Build Coastguard Worker 	struct stat sb;
1180*25da2beaSAndroid Build Coastguard Worker 
1181*25da2beaSAndroid Build Coastguard Worker 	/*
1182*25da2beaSAndroid Build Coastguard Worker 	 * Should either be ./exec-target.t or test/exec-target.t
1183*25da2beaSAndroid Build Coastguard Worker 	 */
1184*25da2beaSAndroid Build Coastguard Worker 	sprintf(dst, "%s", path);
1185*25da2beaSAndroid Build Coastguard Worker 	return stat(dst, &sb);
1186*25da2beaSAndroid Build Coastguard Worker }
1187*25da2beaSAndroid Build Coastguard Worker 
test_timeout_link_cancel(void)1188*25da2beaSAndroid Build Coastguard Worker static int test_timeout_link_cancel(void)
1189*25da2beaSAndroid Build Coastguard Worker {
1190*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
1191*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
1192*25da2beaSAndroid Build Coastguard Worker 	char prog_path[PATH_MAX];
1193*25da2beaSAndroid Build Coastguard Worker 	pid_t p;
1194*25da2beaSAndroid Build Coastguard Worker 	int ret, i, wstatus;
1195*25da2beaSAndroid Build Coastguard Worker 
1196*25da2beaSAndroid Build Coastguard Worker 	if (fill_exec_target(prog_path, "./exec-target.t") &&
1197*25da2beaSAndroid Build Coastguard Worker 	    fill_exec_target(prog_path, "test/exec-target.t")) {
1198*25da2beaSAndroid Build Coastguard Worker 		fprintf(stdout, "Can't find exec-target, skipping\n");
1199*25da2beaSAndroid Build Coastguard Worker 		return 0;
1200*25da2beaSAndroid Build Coastguard Worker 	}
1201*25da2beaSAndroid Build Coastguard Worker 
1202*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
1203*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1204*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring create failed: %d\n", ret);
1205*25da2beaSAndroid Build Coastguard Worker 		return 1;
1206*25da2beaSAndroid Build Coastguard Worker 	}
1207*25da2beaSAndroid Build Coastguard Worker 
1208*25da2beaSAndroid Build Coastguard Worker 	p = fork();
1209*25da2beaSAndroid Build Coastguard Worker 	if (p == -1) {
1210*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "fork() failed\n");
1211*25da2beaSAndroid Build Coastguard Worker 		return 1;
1212*25da2beaSAndroid Build Coastguard Worker 	}
1213*25da2beaSAndroid Build Coastguard Worker 
1214*25da2beaSAndroid Build Coastguard Worker 	if (p == 0) {
1215*25da2beaSAndroid Build Coastguard Worker 		struct io_uring_sqe *sqe;
1216*25da2beaSAndroid Build Coastguard Worker 		struct __kernel_timespec ts;
1217*25da2beaSAndroid Build Coastguard Worker 
1218*25da2beaSAndroid Build Coastguard Worker 		msec_to_ts(&ts, 10000);
1219*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(&ring);
1220*25da2beaSAndroid Build Coastguard Worker 		io_uring_prep_timeout(sqe, &ts, 0, 0);
1221*25da2beaSAndroid Build Coastguard Worker 		sqe->flags |= IOSQE_IO_LINK;
1222*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = 0;
1223*25da2beaSAndroid Build Coastguard Worker 
1224*25da2beaSAndroid Build Coastguard Worker 		sqe = io_uring_get_sqe(&ring);
1225*25da2beaSAndroid Build Coastguard Worker 		io_uring_prep_nop(sqe);
1226*25da2beaSAndroid Build Coastguard Worker 		sqe->user_data = 1;
1227*25da2beaSAndroid Build Coastguard Worker 
1228*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_submit(&ring);
1229*25da2beaSAndroid Build Coastguard Worker 		if (ret != 2) {
1230*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "%s: got %d, wanted 1\n", __FUNCTION__, ret);
1231*25da2beaSAndroid Build Coastguard Worker 			exit(1);
1232*25da2beaSAndroid Build Coastguard Worker 		}
1233*25da2beaSAndroid Build Coastguard Worker 
1234*25da2beaSAndroid Build Coastguard Worker 		/* trigger full cancellation */
1235*25da2beaSAndroid Build Coastguard Worker 		ret = execl(prog_path, prog_path, NULL);
1236*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1237*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "exec failed %i\n", errno);
1238*25da2beaSAndroid Build Coastguard Worker 			exit(1);
1239*25da2beaSAndroid Build Coastguard Worker 		}
1240*25da2beaSAndroid Build Coastguard Worker 		exit(0);
1241*25da2beaSAndroid Build Coastguard Worker 	}
1242*25da2beaSAndroid Build Coastguard Worker 
1243*25da2beaSAndroid Build Coastguard Worker 	if (waitpid(p, &wstatus, 0) == (pid_t)-1) {
1244*25da2beaSAndroid Build Coastguard Worker 		perror("waitpid()");
1245*25da2beaSAndroid Build Coastguard Worker 		return 1;
1246*25da2beaSAndroid Build Coastguard Worker 	}
1247*25da2beaSAndroid Build Coastguard Worker 	if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) {
1248*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus));
1249*25da2beaSAndroid Build Coastguard Worker 		return 1;
1250*25da2beaSAndroid Build Coastguard Worker 	}
1251*25da2beaSAndroid Build Coastguard Worker 
1252*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; ++i) {
1253*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(&ring, &cqe);
1254*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1255*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait_cqe=%d\n", ret);
1256*25da2beaSAndroid Build Coastguard Worker 			return 1;
1257*25da2beaSAndroid Build Coastguard Worker 		}
1258*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res != -ECANCELED) {
1259*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "invalid result, user_data: %i res: %i\n",
1260*25da2beaSAndroid Build Coastguard Worker 					(int)cqe->user_data, cqe->res);
1261*25da2beaSAndroid Build Coastguard Worker 			return 1;
1262*25da2beaSAndroid Build Coastguard Worker 		}
1263*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(&ring, cqe);
1264*25da2beaSAndroid Build Coastguard Worker 	}
1265*25da2beaSAndroid Build Coastguard Worker 
1266*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
1267*25da2beaSAndroid Build Coastguard Worker 	return 0;
1268*25da2beaSAndroid Build Coastguard Worker }
1269*25da2beaSAndroid Build Coastguard Worker 
1270*25da2beaSAndroid Build Coastguard Worker 
test_not_failing_links(void)1271*25da2beaSAndroid Build Coastguard Worker static int test_not_failing_links(void)
1272*25da2beaSAndroid Build Coastguard Worker {
1273*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
1274*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
1275*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
1276*25da2beaSAndroid Build Coastguard Worker 	struct __kernel_timespec ts;
1277*25da2beaSAndroid Build Coastguard Worker 	int ret;
1278*25da2beaSAndroid Build Coastguard Worker 
1279*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
1280*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1281*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring create failed: %d\n", ret);
1282*25da2beaSAndroid Build Coastguard Worker 		return 1;
1283*25da2beaSAndroid Build Coastguard Worker 	}
1284*25da2beaSAndroid Build Coastguard Worker 
1285*25da2beaSAndroid Build Coastguard Worker 	msec_to_ts(&ts, 1);
1286*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(&ring);
1287*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_ETIME_SUCCESS);
1288*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
1289*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
1290*25da2beaSAndroid Build Coastguard Worker 
1291*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(&ring);
1292*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_nop(sqe);
1293*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
1294*25da2beaSAndroid Build Coastguard Worker 
1295*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(&ring);
1296*25da2beaSAndroid Build Coastguard Worker 	if (ret != 2) {
1297*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret);
1298*25da2beaSAndroid Build Coastguard Worker 		return 1;
1299*25da2beaSAndroid Build Coastguard Worker 	}
1300*25da2beaSAndroid Build Coastguard Worker 
1301*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(&ring, &cqe);
1302*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
1303*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
1304*25da2beaSAndroid Build Coastguard Worker 		return 1;
1305*25da2beaSAndroid Build Coastguard Worker 	} else if (cqe->user_data == 1 && cqe->res == -EINVAL) {
1306*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ETIME_SUCCESS is not supported, skip\n");
1307*25da2beaSAndroid Build Coastguard Worker 		goto done;
1308*25da2beaSAndroid Build Coastguard Worker 	} else if (cqe->res != -ETIME || cqe->user_data != 1) {
1309*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "timeout failed %i %i\n", cqe->res,
1310*25da2beaSAndroid Build Coastguard Worker 				(int)cqe->user_data);
1311*25da2beaSAndroid Build Coastguard Worker 		return 1;
1312*25da2beaSAndroid Build Coastguard Worker 	}
1313*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(&ring, cqe);
1314*25da2beaSAndroid Build Coastguard Worker 
1315*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(&ring, &cqe);
1316*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
1317*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret);
1318*25da2beaSAndroid Build Coastguard Worker 		return 1;
1319*25da2beaSAndroid Build Coastguard Worker 	} else if (cqe->res || cqe->user_data != 2) {
1320*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "nop failed %i %i\n", cqe->res,
1321*25da2beaSAndroid Build Coastguard Worker 				(int)cqe->user_data);
1322*25da2beaSAndroid Build Coastguard Worker 		return 1;
1323*25da2beaSAndroid Build Coastguard Worker 	}
1324*25da2beaSAndroid Build Coastguard Worker done:
1325*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(&ring, cqe);
1326*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
1327*25da2beaSAndroid Build Coastguard Worker 	return 0;
1328*25da2beaSAndroid Build Coastguard Worker }
1329*25da2beaSAndroid Build Coastguard Worker 
1330*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])1331*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
1332*25da2beaSAndroid Build Coastguard Worker {
1333*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring, sqpoll_ring;
1334*25da2beaSAndroid Build Coastguard Worker 	bool has_timeout_update, sqpoll;
1335*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_params p = { };
1336*25da2beaSAndroid Build Coastguard Worker 	int ret;
1337*25da2beaSAndroid Build Coastguard Worker 
1338*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
1339*25da2beaSAndroid Build Coastguard Worker 		return 0;
1340*25da2beaSAndroid Build Coastguard Worker 
1341*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init_params(8, &ring, &p);
1342*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1343*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring setup failed\n");
1344*25da2beaSAndroid Build Coastguard Worker 		return 1;
1345*25da2beaSAndroid Build Coastguard Worker 	}
1346*25da2beaSAndroid Build Coastguard Worker 
1347*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &sqpoll_ring, IORING_SETUP_SQPOLL);
1348*25da2beaSAndroid Build Coastguard Worker 	sqpoll = !ret;
1349*25da2beaSAndroid Build Coastguard Worker 
1350*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout(&ring);
1351*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1352*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout failed\n");
1353*25da2beaSAndroid Build Coastguard Worker 		return ret;
1354*25da2beaSAndroid Build Coastguard Worker 	}
1355*25da2beaSAndroid Build Coastguard Worker 	if (not_supported)
1356*25da2beaSAndroid Build Coastguard Worker 		return 0;
1357*25da2beaSAndroid Build Coastguard Worker 
1358*25da2beaSAndroid Build Coastguard Worker 	ret = test_multi_timeout(&ring);
1359*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1360*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_multi_timeout failed\n");
1361*25da2beaSAndroid Build Coastguard Worker 		return ret;
1362*25da2beaSAndroid Build Coastguard Worker 	}
1363*25da2beaSAndroid Build Coastguard Worker 
1364*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_abs(&ring);
1365*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1366*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_abs failed\n");
1367*25da2beaSAndroid Build Coastguard Worker 		return ret;
1368*25da2beaSAndroid Build Coastguard Worker 	}
1369*25da2beaSAndroid Build Coastguard Worker 
1370*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_remove(&ring);
1371*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1372*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_remove failed\n");
1373*25da2beaSAndroid Build Coastguard Worker 		return ret;
1374*25da2beaSAndroid Build Coastguard Worker 	}
1375*25da2beaSAndroid Build Coastguard Worker 
1376*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_remove_notfound(&ring);
1377*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1378*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_remove_notfound failed\n");
1379*25da2beaSAndroid Build Coastguard Worker 		return ret;
1380*25da2beaSAndroid Build Coastguard Worker 	}
1381*25da2beaSAndroid Build Coastguard Worker 
1382*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_many(&ring);
1383*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1384*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_many failed\n");
1385*25da2beaSAndroid Build Coastguard Worker 		return ret;
1386*25da2beaSAndroid Build Coastguard Worker 	}
1387*25da2beaSAndroid Build Coastguard Worker 
1388*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_nr(&ring, 1);
1389*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1390*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_nr(1) failed\n");
1391*25da2beaSAndroid Build Coastguard Worker 		return ret;
1392*25da2beaSAndroid Build Coastguard Worker 	}
1393*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_nr(&ring, 2);
1394*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1395*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_nr(2) failed\n");
1396*25da2beaSAndroid Build Coastguard Worker 		return ret;
1397*25da2beaSAndroid Build Coastguard Worker 	}
1398*25da2beaSAndroid Build Coastguard Worker 
1399*25da2beaSAndroid Build Coastguard Worker 	ret = test_multi_timeout_nr(&ring);
1400*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1401*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_multi_timeout_nr failed\n");
1402*25da2beaSAndroid Build Coastguard Worker 		return ret;
1403*25da2beaSAndroid Build Coastguard Worker 	}
1404*25da2beaSAndroid Build Coastguard Worker 
1405*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_flags1(&ring);
1406*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1407*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_timeout_flags1 failed\n");
1408*25da2beaSAndroid Build Coastguard Worker 		return ret;
1409*25da2beaSAndroid Build Coastguard Worker 	}
1410*25da2beaSAndroid Build Coastguard Worker 
1411*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_flags2(&ring);
1412*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1413*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_timeout_flags2 failed\n");
1414*25da2beaSAndroid Build Coastguard Worker 		return ret;
1415*25da2beaSAndroid Build Coastguard Worker 	}
1416*25da2beaSAndroid Build Coastguard Worker 
1417*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_flags3(&ring);
1418*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1419*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_timeout_flags3 failed\n");
1420*25da2beaSAndroid Build Coastguard Worker 		return ret;
1421*25da2beaSAndroid Build Coastguard Worker 	}
1422*25da2beaSAndroid Build Coastguard Worker 
1423*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_wait(&ring, &p);
1424*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1425*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_wait failed\n");
1426*25da2beaSAndroid Build Coastguard Worker 		return ret;
1427*25da2beaSAndroid Build Coastguard Worker 	}
1428*25da2beaSAndroid Build Coastguard Worker 
1429*25da2beaSAndroid Build Coastguard Worker 	/* io_uring_wait_cqes() may have left a timeout, reinit ring */
1430*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
1431*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
1432*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1433*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring setup failed\n");
1434*25da2beaSAndroid Build Coastguard Worker 		return 1;
1435*25da2beaSAndroid Build Coastguard Worker 	}
1436*25da2beaSAndroid Build Coastguard Worker 
1437*25da2beaSAndroid Build Coastguard Worker 	ret = test_update_nonexistent_timeout(&ring);
1438*25da2beaSAndroid Build Coastguard Worker 	has_timeout_update = (ret != -EINVAL);
1439*25da2beaSAndroid Build Coastguard Worker 	if (has_timeout_update) {
1440*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1441*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_nonexistent_timeout failed\n");
1442*25da2beaSAndroid Build Coastguard Worker 			return ret;
1443*25da2beaSAndroid Build Coastguard Worker 		}
1444*25da2beaSAndroid Build Coastguard Worker 
1445*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_invalid_flags(&ring);
1446*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1447*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_invalid_flags failed\n");
1448*25da2beaSAndroid Build Coastguard Worker 			return ret;
1449*25da2beaSAndroid Build Coastguard Worker 		}
1450*25da2beaSAndroid Build Coastguard Worker 
1451*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_timeout(&ring, 0, false, false, false);
1452*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1453*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_timeout failed\n");
1454*25da2beaSAndroid Build Coastguard Worker 			return ret;
1455*25da2beaSAndroid Build Coastguard Worker 		}
1456*25da2beaSAndroid Build Coastguard Worker 
1457*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_timeout(&ring, 1, false, false, false);
1458*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1459*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_timeout 1ms failed\n");
1460*25da2beaSAndroid Build Coastguard Worker 			return ret;
1461*25da2beaSAndroid Build Coastguard Worker 		}
1462*25da2beaSAndroid Build Coastguard Worker 
1463*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_timeout(&ring, 1000, false, false, false);
1464*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1465*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_timeout 1s failed\n");
1466*25da2beaSAndroid Build Coastguard Worker 			return ret;
1467*25da2beaSAndroid Build Coastguard Worker 		}
1468*25da2beaSAndroid Build Coastguard Worker 
1469*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_timeout(&ring, 0, true, true, false);
1470*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1471*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_timeout abs failed\n");
1472*25da2beaSAndroid Build Coastguard Worker 			return ret;
1473*25da2beaSAndroid Build Coastguard Worker 		}
1474*25da2beaSAndroid Build Coastguard Worker 
1475*25da2beaSAndroid Build Coastguard Worker 
1476*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_timeout(&ring, 0, false, true, false);
1477*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1478*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_timeout async failed\n");
1479*25da2beaSAndroid Build Coastguard Worker 			return ret;
1480*25da2beaSAndroid Build Coastguard Worker 		}
1481*25da2beaSAndroid Build Coastguard Worker 
1482*25da2beaSAndroid Build Coastguard Worker 		ret = test_update_timeout(&ring, 0, false, false, true);
1483*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
1484*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_update_timeout linked failed\n");
1485*25da2beaSAndroid Build Coastguard Worker 			return ret;
1486*25da2beaSAndroid Build Coastguard Worker 		}
1487*25da2beaSAndroid Build Coastguard Worker 
1488*25da2beaSAndroid Build Coastguard Worker 		if (sqpoll) {
1489*25da2beaSAndroid Build Coastguard Worker 			ret = test_update_timeout(&sqpoll_ring, 0, false, false,
1490*25da2beaSAndroid Build Coastguard Worker 						  false);
1491*25da2beaSAndroid Build Coastguard Worker 			if (ret) {
1492*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "test_update_timeout sqpoll"
1493*25da2beaSAndroid Build Coastguard Worker 						"failed\n");
1494*25da2beaSAndroid Build Coastguard Worker 				return ret;
1495*25da2beaSAndroid Build Coastguard Worker 			}
1496*25da2beaSAndroid Build Coastguard Worker 		}
1497*25da2beaSAndroid Build Coastguard Worker 	}
1498*25da2beaSAndroid Build Coastguard Worker 
1499*25da2beaSAndroid Build Coastguard Worker 	/*
1500*25da2beaSAndroid Build Coastguard Worker 	 * this test must go last, it kills the ring
1501*25da2beaSAndroid Build Coastguard Worker 	 */
1502*25da2beaSAndroid Build Coastguard Worker 	ret = test_single_timeout_exit(&ring);
1503*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1504*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_single_timeout_exit failed\n");
1505*25da2beaSAndroid Build Coastguard Worker 		return ret;
1506*25da2beaSAndroid Build Coastguard Worker 	}
1507*25da2beaSAndroid Build Coastguard Worker 
1508*25da2beaSAndroid Build Coastguard Worker 	ret = test_timeout_link_cancel();
1509*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1510*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_timeout_link_cancel failed\n");
1511*25da2beaSAndroid Build Coastguard Worker 		return ret;
1512*25da2beaSAndroid Build Coastguard Worker 	}
1513*25da2beaSAndroid Build Coastguard Worker 
1514*25da2beaSAndroid Build Coastguard Worker 	ret = test_not_failing_links();
1515*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
1516*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_not_failing_links failed\n");
1517*25da2beaSAndroid Build Coastguard Worker 		return ret;
1518*25da2beaSAndroid Build Coastguard Worker 	}
1519*25da2beaSAndroid Build Coastguard Worker 
1520*25da2beaSAndroid Build Coastguard Worker 	if (sqpoll)
1521*25da2beaSAndroid Build Coastguard Worker 		io_uring_queue_exit(&sqpoll_ring);
1522*25da2beaSAndroid Build Coastguard Worker 	return 0;
1523*25da2beaSAndroid Build Coastguard Worker }
1524