xref: /aosp_15_r20/external/liburing/test/nop.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Description: run various nop 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 
13 #include "liburing.h"
14 #include "test.h"
15 
16 static int seq;
17 
test_single_nop(struct io_uring * ring,unsigned req_flags)18 static int test_single_nop(struct io_uring *ring, unsigned req_flags)
19 {
20 	struct io_uring_cqe *cqe;
21 	struct io_uring_sqe *sqe;
22 	int ret;
23 	bool cqe32 = (ring->flags & IORING_SETUP_CQE32);
24 
25 	sqe = io_uring_get_sqe(ring);
26 	if (!sqe) {
27 		fprintf(stderr, "get sqe failed\n");
28 		goto err;
29 	}
30 
31 	io_uring_prep_nop(sqe);
32 	sqe->user_data = ++seq;
33 	sqe->flags |= req_flags;
34 
35 	ret = io_uring_submit(ring);
36 	if (ret <= 0) {
37 		fprintf(stderr, "sqe submit failed: %d\n", ret);
38 		goto err;
39 	}
40 
41 	ret = io_uring_wait_cqe(ring, &cqe);
42 	if (ret < 0) {
43 		fprintf(stderr, "wait completion %d\n", ret);
44 		goto err;
45 	}
46 	if (!cqe->user_data) {
47 		fprintf(stderr, "Unexpected 0 user_data\n");
48 		goto err;
49 	}
50 	if (cqe32) {
51 		if (cqe->big_cqe[0] != 0) {
52 			fprintf(stderr, "Unexpected extra1\n");
53 			goto err;
54 
55 		}
56 		if (cqe->big_cqe[1] != 0) {
57 			fprintf(stderr, "Unexpected extra2\n");
58 			goto err;
59 		}
60 	}
61 	io_uring_cqe_seen(ring, cqe);
62 	return 0;
63 err:
64 	return 1;
65 }
66 
test_barrier_nop(struct io_uring * ring,unsigned req_flags)67 static int test_barrier_nop(struct io_uring *ring, unsigned req_flags)
68 {
69 	struct io_uring_cqe *cqe;
70 	struct io_uring_sqe *sqe;
71 	int ret, i;
72 	bool cqe32 = (ring->flags & IORING_SETUP_CQE32);
73 
74 	for (i = 0; i < 8; i++) {
75 		sqe = io_uring_get_sqe(ring);
76 		if (!sqe) {
77 			fprintf(stderr, "get sqe failed\n");
78 			goto err;
79 		}
80 
81 		io_uring_prep_nop(sqe);
82 		if (i == 4)
83 			sqe->flags = IOSQE_IO_DRAIN;
84 		sqe->user_data = ++seq;
85 		sqe->flags |= req_flags;
86 	}
87 
88 	ret = io_uring_submit(ring);
89 	if (ret < 0) {
90 		fprintf(stderr, "sqe submit failed: %d\n", ret);
91 		goto err;
92 	} else if (ret < 8) {
93 		fprintf(stderr, "Submitted only %d\n", ret);
94 		goto err;
95 	}
96 
97 	for (i = 0; i < 8; i++) {
98 		ret = io_uring_wait_cqe(ring, &cqe);
99 		if (ret < 0) {
100 			fprintf(stderr, "wait completion %d\n", ret);
101 			goto err;
102 		}
103 		if (!cqe->user_data) {
104 			fprintf(stderr, "Unexpected 0 user_data\n");
105 			goto err;
106 		}
107 		if (cqe32) {
108 			if (cqe->big_cqe[0] != 0) {
109 				fprintf(stderr, "Unexpected extra1\n");
110 				goto err;
111 			}
112 			if (cqe->big_cqe[1] != 0) {
113 				fprintf(stderr, "Unexpected extra2\n");
114 				goto err;
115 			}
116 		}
117 		io_uring_cqe_seen(ring, cqe);
118 	}
119 
120 	return 0;
121 err:
122 	return 1;
123 }
124 
test_ring(unsigned flags)125 static int test_ring(unsigned flags)
126 {
127 	struct io_uring ring;
128 	struct io_uring_params p = { };
129 	int ret, i;
130 
131 	p.flags = flags;
132 	ret = io_uring_queue_init_params(8, &ring, &p);
133 	if (ret) {
134 		if (ret == -EINVAL)
135 			return 0;
136 		fprintf(stderr, "ring setup failed: %d\n", ret);
137 		return 1;
138 	}
139 
140 	for (i = 0; i < 1000; i++) {
141 		unsigned req_flags = (i & 1) ? IOSQE_ASYNC : 0;
142 
143 		ret = test_single_nop(&ring, req_flags);
144 		if (ret) {
145 			fprintf(stderr, "test_single_nop failed\n");
146 			goto err;
147 		}
148 
149 		ret = test_barrier_nop(&ring, req_flags);
150 		if (ret) {
151 			fprintf(stderr, "test_barrier_nop failed\n");
152 			goto err;
153 		}
154 	}
155 err:
156 	io_uring_queue_exit(&ring);
157 	return ret;
158 }
159 
main(int argc,char * argv[])160 int main(int argc, char *argv[])
161 {
162 	int ret;
163 
164 	if (argc > 1)
165 		return 0;
166 
167 	FOR_ALL_TEST_CONFIGS {
168 		ret = test_ring(IORING_GET_TEST_CONFIG_FLAGS());
169 		if (ret) {
170 			fprintf(stderr, "Normal ring test failed: %s\n",
171 					IORING_GET_TEST_CONFIG_DESCRIPTION());
172 			return ret;
173 		}
174 	}
175 
176 	return 0;
177 }
178