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