xref: /aosp_15_r20/external/liburing/test/buf-ring.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 shared buffer ring sanity checks
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 
13*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
14*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
15*25da2beaSAndroid Build Coastguard Worker 
16*25da2beaSAndroid Build Coastguard Worker static int no_buf_ring;
17*25da2beaSAndroid Build Coastguard Worker 
18*25da2beaSAndroid Build Coastguard Worker /* test trying to register classic group when ring group exists */
test_mixed_reg2(int bgid)19*25da2beaSAndroid Build Coastguard Worker static int test_mixed_reg2(int bgid)
20*25da2beaSAndroid Build Coastguard Worker {
21*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_buf_reg reg = { };
22*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
23*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
24*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
25*25da2beaSAndroid Build Coastguard Worker 	void *ptr, *bufs;
26*25da2beaSAndroid Build Coastguard Worker 	int ret;
27*25da2beaSAndroid Build Coastguard Worker 
28*25da2beaSAndroid Build Coastguard Worker 	ret = t_create_ring(1, &ring, 0);
29*25da2beaSAndroid Build Coastguard Worker 	if (ret == T_SETUP_SKIP)
30*25da2beaSAndroid Build Coastguard Worker 		return 0;
31*25da2beaSAndroid Build Coastguard Worker 	else if (ret != T_SETUP_OK)
32*25da2beaSAndroid Build Coastguard Worker 		return 1;
33*25da2beaSAndroid Build Coastguard Worker 
34*25da2beaSAndroid Build Coastguard Worker 	if (posix_memalign(&ptr, 4096, 4096))
35*25da2beaSAndroid Build Coastguard Worker 		return 1;
36*25da2beaSAndroid Build Coastguard Worker 
37*25da2beaSAndroid Build Coastguard Worker 	reg.ring_addr = (unsigned long) ptr;
38*25da2beaSAndroid Build Coastguard Worker 	reg.ring_entries = 32;
39*25da2beaSAndroid Build Coastguard Worker 	reg.bgid = bgid;
40*25da2beaSAndroid Build Coastguard Worker 
41*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buf_ring(&ring, &reg, 0);
42*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
43*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
44*25da2beaSAndroid Build Coastguard Worker 		return 1;
45*25da2beaSAndroid Build Coastguard Worker 	}
46*25da2beaSAndroid Build Coastguard Worker 
47*25da2beaSAndroid Build Coastguard Worker 	/* provide classic buffers, group 1 */
48*25da2beaSAndroid Build Coastguard Worker 	bufs = malloc(8 * 1024);
49*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(&ring);
50*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_provide_buffers(sqe, bufs, 1024, 8, bgid, 0);
51*25da2beaSAndroid Build Coastguard Worker 	io_uring_submit(&ring);
52*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(&ring, &cqe);
53*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
54*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait_cqe %d\n", ret);
55*25da2beaSAndroid Build Coastguard Worker 		return 1;
56*25da2beaSAndroid Build Coastguard Worker 	}
57*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res != -EEXIST && cqe->res != -EINVAL) {
58*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "cqe res %d\n", cqe->res);
59*25da2beaSAndroid Build Coastguard Worker 		return 1;
60*25da2beaSAndroid Build Coastguard Worker 	}
61*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(&ring, cqe);
62*25da2beaSAndroid Build Coastguard Worker 
63*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
64*25da2beaSAndroid Build Coastguard Worker 	return 0;
65*25da2beaSAndroid Build Coastguard Worker }
66*25da2beaSAndroid Build Coastguard Worker 
67*25da2beaSAndroid Build Coastguard Worker /* test trying to register ring group when  classic group exists */
test_mixed_reg(int bgid)68*25da2beaSAndroid Build Coastguard Worker static int test_mixed_reg(int bgid)
69*25da2beaSAndroid Build Coastguard Worker {
70*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_buf_reg reg = { };
71*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
72*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
73*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
74*25da2beaSAndroid Build Coastguard Worker 	void *ptr, *bufs;
75*25da2beaSAndroid Build Coastguard Worker 	int ret;
76*25da2beaSAndroid Build Coastguard Worker 
77*25da2beaSAndroid Build Coastguard Worker 	ret = t_create_ring(1, &ring, 0);
78*25da2beaSAndroid Build Coastguard Worker 	if (ret == T_SETUP_SKIP)
79*25da2beaSAndroid Build Coastguard Worker 		return 0;
80*25da2beaSAndroid Build Coastguard Worker 	else if (ret != T_SETUP_OK)
81*25da2beaSAndroid Build Coastguard Worker 		return 1;
82*25da2beaSAndroid Build Coastguard Worker 
83*25da2beaSAndroid Build Coastguard Worker 	/* provide classic buffers, group 1 */
84*25da2beaSAndroid Build Coastguard Worker 	bufs = malloc(8 * 1024);
85*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(&ring);
86*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_provide_buffers(sqe, bufs, 1024, 8, bgid, 0);
87*25da2beaSAndroid Build Coastguard Worker 	io_uring_submit(&ring);
88*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(&ring, &cqe);
89*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
90*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait_cqe %d\n", ret);
91*25da2beaSAndroid Build Coastguard Worker 		return 1;
92*25da2beaSAndroid Build Coastguard Worker 	}
93*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res) {
94*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "cqe res %d\n", cqe->res);
95*25da2beaSAndroid Build Coastguard Worker 		return 1;
96*25da2beaSAndroid Build Coastguard Worker 	}
97*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(&ring, cqe);
98*25da2beaSAndroid Build Coastguard Worker 
99*25da2beaSAndroid Build Coastguard Worker 	if (posix_memalign(&ptr, 4096, 4096))
100*25da2beaSAndroid Build Coastguard Worker 		return 1;
101*25da2beaSAndroid Build Coastguard Worker 
102*25da2beaSAndroid Build Coastguard Worker 	reg.ring_addr = (unsigned long) ptr;
103*25da2beaSAndroid Build Coastguard Worker 	reg.ring_entries = 32;
104*25da2beaSAndroid Build Coastguard Worker 	reg.bgid = bgid;
105*25da2beaSAndroid Build Coastguard Worker 
106*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buf_ring(&ring, &reg, 0);
107*25da2beaSAndroid Build Coastguard Worker 	if (ret != -EEXIST) {
108*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
109*25da2beaSAndroid Build Coastguard Worker 		return 1;
110*25da2beaSAndroid Build Coastguard Worker 	}
111*25da2beaSAndroid Build Coastguard Worker 
112*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
113*25da2beaSAndroid Build Coastguard Worker 	return 0;
114*25da2beaSAndroid Build Coastguard Worker }
115*25da2beaSAndroid Build Coastguard Worker 
test_double_reg_unreg(int bgid)116*25da2beaSAndroid Build Coastguard Worker static int test_double_reg_unreg(int bgid)
117*25da2beaSAndroid Build Coastguard Worker {
118*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_buf_reg reg = { };
119*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
120*25da2beaSAndroid Build Coastguard Worker 	void *ptr;
121*25da2beaSAndroid Build Coastguard Worker 	int ret;
122*25da2beaSAndroid Build Coastguard Worker 
123*25da2beaSAndroid Build Coastguard Worker 	ret = t_create_ring(1, &ring, 0);
124*25da2beaSAndroid Build Coastguard Worker 	if (ret == T_SETUP_SKIP)
125*25da2beaSAndroid Build Coastguard Worker 		return 0;
126*25da2beaSAndroid Build Coastguard Worker 	else if (ret != T_SETUP_OK)
127*25da2beaSAndroid Build Coastguard Worker 		return 1;
128*25da2beaSAndroid Build Coastguard Worker 
129*25da2beaSAndroid Build Coastguard Worker 	if (posix_memalign(&ptr, 4096, 4096))
130*25da2beaSAndroid Build Coastguard Worker 		return 1;
131*25da2beaSAndroid Build Coastguard Worker 
132*25da2beaSAndroid Build Coastguard Worker 	reg.ring_addr = (unsigned long) ptr;
133*25da2beaSAndroid Build Coastguard Worker 	reg.ring_entries = 32;
134*25da2beaSAndroid Build Coastguard Worker 	reg.bgid = bgid;
135*25da2beaSAndroid Build Coastguard Worker 
136*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buf_ring(&ring, &reg, 0);
137*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
138*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
139*25da2beaSAndroid Build Coastguard Worker 		return 1;
140*25da2beaSAndroid Build Coastguard Worker 	}
141*25da2beaSAndroid Build Coastguard Worker 
142*25da2beaSAndroid Build Coastguard Worker 	/* check that 2nd register with same bgid fails */
143*25da2beaSAndroid Build Coastguard Worker 	reg.ring_addr = (unsigned long) ptr;
144*25da2beaSAndroid Build Coastguard Worker 	reg.ring_entries = 32;
145*25da2beaSAndroid Build Coastguard Worker 	reg.bgid = bgid;
146*25da2beaSAndroid Build Coastguard Worker 
147*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buf_ring(&ring, &reg, 0);
148*25da2beaSAndroid Build Coastguard Worker 	if (ret != -EEXIST) {
149*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
150*25da2beaSAndroid Build Coastguard Worker 		return 1;
151*25da2beaSAndroid Build Coastguard Worker 	}
152*25da2beaSAndroid Build Coastguard Worker 
153*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_unregister_buf_ring(&ring, bgid);
154*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
155*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
156*25da2beaSAndroid Build Coastguard Worker 		return 1;
157*25da2beaSAndroid Build Coastguard Worker 	}
158*25da2beaSAndroid Build Coastguard Worker 
159*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_unregister_buf_ring(&ring, bgid);
160*25da2beaSAndroid Build Coastguard Worker 	if (ret != -EINVAL && ret != -ENOENT) {
161*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
162*25da2beaSAndroid Build Coastguard Worker 		return 1;
163*25da2beaSAndroid Build Coastguard Worker 	}
164*25da2beaSAndroid Build Coastguard Worker 
165*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
166*25da2beaSAndroid Build Coastguard Worker 	return 0;
167*25da2beaSAndroid Build Coastguard Worker }
168*25da2beaSAndroid Build Coastguard Worker 
test_reg_unreg(int bgid)169*25da2beaSAndroid Build Coastguard Worker static int test_reg_unreg(int bgid)
170*25da2beaSAndroid Build Coastguard Worker {
171*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_buf_reg reg = { };
172*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
173*25da2beaSAndroid Build Coastguard Worker 	void *ptr;
174*25da2beaSAndroid Build Coastguard Worker 	int ret;
175*25da2beaSAndroid Build Coastguard Worker 
176*25da2beaSAndroid Build Coastguard Worker 	ret = t_create_ring(1, &ring, 0);
177*25da2beaSAndroid Build Coastguard Worker 	if (ret == T_SETUP_SKIP)
178*25da2beaSAndroid Build Coastguard Worker 		return 0;
179*25da2beaSAndroid Build Coastguard Worker 	else if (ret != T_SETUP_OK)
180*25da2beaSAndroid Build Coastguard Worker 		return 1;
181*25da2beaSAndroid Build Coastguard Worker 
182*25da2beaSAndroid Build Coastguard Worker 	if (posix_memalign(&ptr, 4096, 4096))
183*25da2beaSAndroid Build Coastguard Worker 		return 1;
184*25da2beaSAndroid Build Coastguard Worker 
185*25da2beaSAndroid Build Coastguard Worker 	reg.ring_addr = (unsigned long) ptr;
186*25da2beaSAndroid Build Coastguard Worker 	reg.ring_entries = 32;
187*25da2beaSAndroid Build Coastguard Worker 	reg.bgid = bgid;
188*25da2beaSAndroid Build Coastguard Worker 
189*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buf_ring(&ring, &reg, 0);
190*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
191*25da2beaSAndroid Build Coastguard Worker 		if (ret == -EINVAL) {
192*25da2beaSAndroid Build Coastguard Worker 			no_buf_ring = 1;
193*25da2beaSAndroid Build Coastguard Worker 			return 0;
194*25da2beaSAndroid Build Coastguard Worker 		}
195*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
196*25da2beaSAndroid Build Coastguard Worker 		return 1;
197*25da2beaSAndroid Build Coastguard Worker 	}
198*25da2beaSAndroid Build Coastguard Worker 
199*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_unregister_buf_ring(&ring, bgid);
200*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
201*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
202*25da2beaSAndroid Build Coastguard Worker 		return 1;
203*25da2beaSAndroid Build Coastguard Worker 	}
204*25da2beaSAndroid Build Coastguard Worker 
205*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
206*25da2beaSAndroid Build Coastguard Worker 	return 0;
207*25da2beaSAndroid Build Coastguard Worker }
208*25da2beaSAndroid Build Coastguard Worker 
test_one_read(int fd,int bgid,struct io_uring * ring)209*25da2beaSAndroid Build Coastguard Worker static int test_one_read(int fd, int bgid, struct io_uring *ring)
210*25da2beaSAndroid Build Coastguard Worker {
211*25da2beaSAndroid Build Coastguard Worker 	int ret;
212*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
213*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
214*25da2beaSAndroid Build Coastguard Worker 
215*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
216*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
217*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
218*25da2beaSAndroid Build Coastguard Worker 		return -1;
219*25da2beaSAndroid Build Coastguard Worker 	}
220*25da2beaSAndroid Build Coastguard Worker 
221*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_read(sqe, fd, NULL, 1, 0);
222*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_BUFFER_SELECT;
223*25da2beaSAndroid Build Coastguard Worker 	sqe->buf_group = bgid;
224*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
225*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
226*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
227*25da2beaSAndroid Build Coastguard Worker 		return -1;
228*25da2beaSAndroid Build Coastguard Worker 	}
229*25da2beaSAndroid Build Coastguard Worker 
230*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
231*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
232*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
233*25da2beaSAndroid Build Coastguard Worker 		return -1;
234*25da2beaSAndroid Build Coastguard Worker 	}
235*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
236*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
237*25da2beaSAndroid Build Coastguard Worker 
238*25da2beaSAndroid Build Coastguard Worker 	if (ret == -ENOBUFS)
239*25da2beaSAndroid Build Coastguard Worker 		return ret;
240*25da2beaSAndroid Build Coastguard Worker 
241*25da2beaSAndroid Build Coastguard Worker 	if (ret != 1) {
242*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "read result %d\n", ret);
243*25da2beaSAndroid Build Coastguard Worker 		return -1;
244*25da2beaSAndroid Build Coastguard Worker 	}
245*25da2beaSAndroid Build Coastguard Worker 
246*25da2beaSAndroid Build Coastguard Worker 	return cqe->flags >> 16;
247*25da2beaSAndroid Build Coastguard Worker }
248*25da2beaSAndroid Build Coastguard Worker 
test_running(int bgid,int entries,int loops)249*25da2beaSAndroid Build Coastguard Worker static int test_running(int bgid, int entries, int loops)
250*25da2beaSAndroid Build Coastguard Worker {
251*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_buf_reg reg = { };
252*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
253*25da2beaSAndroid Build Coastguard Worker 	void *ptr;
254*25da2beaSAndroid Build Coastguard Worker 	char buffer[8];
255*25da2beaSAndroid Build Coastguard Worker 	int ret;
256*25da2beaSAndroid Build Coastguard Worker 	int ring_size = (entries * sizeof(struct io_uring_buf) + 4095) & (~4095);
257*25da2beaSAndroid Build Coastguard Worker 	int ring_mask = io_uring_buf_ring_mask(entries);
258*25da2beaSAndroid Build Coastguard Worker 
259*25da2beaSAndroid Build Coastguard Worker 	int loop, idx;
260*25da2beaSAndroid Build Coastguard Worker 	bool *buffers;
261*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_buf_ring *br;
262*25da2beaSAndroid Build Coastguard Worker 	int read_fd;
263*25da2beaSAndroid Build Coastguard Worker 
264*25da2beaSAndroid Build Coastguard Worker 	ret = t_create_ring(1, &ring, 0);
265*25da2beaSAndroid Build Coastguard Worker 	if (ret == T_SETUP_SKIP)
266*25da2beaSAndroid Build Coastguard Worker 		return 0;
267*25da2beaSAndroid Build Coastguard Worker 	else if (ret != T_SETUP_OK)
268*25da2beaSAndroid Build Coastguard Worker 		return 1;
269*25da2beaSAndroid Build Coastguard Worker 
270*25da2beaSAndroid Build Coastguard Worker 	if (posix_memalign(&ptr, 4096, ring_size))
271*25da2beaSAndroid Build Coastguard Worker 		return 1;
272*25da2beaSAndroid Build Coastguard Worker 
273*25da2beaSAndroid Build Coastguard Worker 	br = (struct io_uring_buf_ring *)ptr;
274*25da2beaSAndroid Build Coastguard Worker 	io_uring_buf_ring_init(br);
275*25da2beaSAndroid Build Coastguard Worker 
276*25da2beaSAndroid Build Coastguard Worker 	buffers = malloc(sizeof(bool) * entries);
277*25da2beaSAndroid Build Coastguard Worker 	if (!buffers)
278*25da2beaSAndroid Build Coastguard Worker 		return 1;
279*25da2beaSAndroid Build Coastguard Worker 
280*25da2beaSAndroid Build Coastguard Worker 	read_fd = open("/dev/zero", O_RDONLY);
281*25da2beaSAndroid Build Coastguard Worker 	if (read_fd < 0)
282*25da2beaSAndroid Build Coastguard Worker 		return 1;
283*25da2beaSAndroid Build Coastguard Worker 
284*25da2beaSAndroid Build Coastguard Worker 	reg.ring_addr = (unsigned long) ptr;
285*25da2beaSAndroid Build Coastguard Worker 	reg.ring_entries = entries;
286*25da2beaSAndroid Build Coastguard Worker 	reg.bgid = bgid;
287*25da2beaSAndroid Build Coastguard Worker 
288*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_register_buf_ring(&ring, &reg, 0);
289*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
290*25da2beaSAndroid Build Coastguard Worker 		/* by now should have checked if this is supported or not */
291*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
292*25da2beaSAndroid Build Coastguard Worker 		return 1;
293*25da2beaSAndroid Build Coastguard Worker 	}
294*25da2beaSAndroid Build Coastguard Worker 
295*25da2beaSAndroid Build Coastguard Worker 	for (loop = 0; loop < loops; loop++) {
296*25da2beaSAndroid Build Coastguard Worker 		memset(buffers, 0, sizeof(bool) * entries);
297*25da2beaSAndroid Build Coastguard Worker 		for (idx = 0; idx < entries; idx++)
298*25da2beaSAndroid Build Coastguard Worker 			io_uring_buf_ring_add(br, buffer, sizeof(buffer), idx, ring_mask, idx);
299*25da2beaSAndroid Build Coastguard Worker 		io_uring_buf_ring_advance(br, entries);
300*25da2beaSAndroid Build Coastguard Worker 
301*25da2beaSAndroid Build Coastguard Worker 		for (idx = 0; idx < entries; idx++) {
302*25da2beaSAndroid Build Coastguard Worker 			memset(buffer, 1, sizeof(buffer));
303*25da2beaSAndroid Build Coastguard Worker 			ret = test_one_read(read_fd, bgid, &ring);
304*25da2beaSAndroid Build Coastguard Worker 			if (ret < 0) {
305*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "bad run %d/%d = %d\n", loop, idx, ret);
306*25da2beaSAndroid Build Coastguard Worker 				return ret;
307*25da2beaSAndroid Build Coastguard Worker 			}
308*25da2beaSAndroid Build Coastguard Worker 			if (buffers[ret]) {
309*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "reused buffer %d/%d = %d!\n", loop, idx, ret);
310*25da2beaSAndroid Build Coastguard Worker 				return 1;
311*25da2beaSAndroid Build Coastguard Worker 			}
312*25da2beaSAndroid Build Coastguard Worker 			if (buffer[0] != 0) {
313*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "unexpected read %d %d/%d = %d!\n",
314*25da2beaSAndroid Build Coastguard Worker 						(int)buffer[0], loop, idx, ret);
315*25da2beaSAndroid Build Coastguard Worker 				return 1;
316*25da2beaSAndroid Build Coastguard Worker 			}
317*25da2beaSAndroid Build Coastguard Worker 			if (buffer[1] != 1) {
318*25da2beaSAndroid Build Coastguard Worker 				fprintf(stderr, "unexpected spilled read %d %d/%d = %d!\n",
319*25da2beaSAndroid Build Coastguard Worker 						(int)buffer[1], loop, idx, ret);
320*25da2beaSAndroid Build Coastguard Worker 				return 1;
321*25da2beaSAndroid Build Coastguard Worker 			}
322*25da2beaSAndroid Build Coastguard Worker 			buffers[ret] = true;
323*25da2beaSAndroid Build Coastguard Worker 		}
324*25da2beaSAndroid Build Coastguard Worker 		ret = test_one_read(read_fd, bgid, &ring);
325*25da2beaSAndroid Build Coastguard Worker 		if (ret != -ENOBUFS) {
326*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "expected enobufs run %d = %d\n", loop, ret);
327*25da2beaSAndroid Build Coastguard Worker 			return 1;
328*25da2beaSAndroid Build Coastguard Worker 		}
329*25da2beaSAndroid Build Coastguard Worker 
330*25da2beaSAndroid Build Coastguard Worker 	}
331*25da2beaSAndroid Build Coastguard Worker 
332*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_unregister_buf_ring(&ring, bgid);
333*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
334*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Buffer ring register failed %d\n", ret);
335*25da2beaSAndroid Build Coastguard Worker 		return 1;
336*25da2beaSAndroid Build Coastguard Worker 	}
337*25da2beaSAndroid Build Coastguard Worker 
338*25da2beaSAndroid Build Coastguard Worker 	close(read_fd);
339*25da2beaSAndroid Build Coastguard Worker 	io_uring_queue_exit(&ring);
340*25da2beaSAndroid Build Coastguard Worker 	free(buffers);
341*25da2beaSAndroid Build Coastguard Worker 	return 0;
342*25da2beaSAndroid Build Coastguard Worker }
343*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])344*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
345*25da2beaSAndroid Build Coastguard Worker {
346*25da2beaSAndroid Build Coastguard Worker 	int bgids[] = { 1, 127, -1 };
347*25da2beaSAndroid Build Coastguard Worker 	int entries[] = {1, 32768, 4096, -1 };
348*25da2beaSAndroid Build Coastguard Worker 	int ret, i;
349*25da2beaSAndroid Build Coastguard Worker 
350*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
351*25da2beaSAndroid Build Coastguard Worker 		return 0;
352*25da2beaSAndroid Build Coastguard Worker 
353*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; bgids[i] != -1; i++) {
354*25da2beaSAndroid Build Coastguard Worker 		ret = test_reg_unreg(bgids[i]);
355*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
356*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_reg_unreg failed\n");
357*25da2beaSAndroid Build Coastguard Worker 			return 1;
358*25da2beaSAndroid Build Coastguard Worker 		}
359*25da2beaSAndroid Build Coastguard Worker 		if (no_buf_ring)
360*25da2beaSAndroid Build Coastguard Worker 			break;
361*25da2beaSAndroid Build Coastguard Worker 
362*25da2beaSAndroid Build Coastguard Worker 		ret = test_double_reg_unreg(bgids[i]);
363*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
364*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_double_reg_unreg failed\n");
365*25da2beaSAndroid Build Coastguard Worker 			return 1;
366*25da2beaSAndroid Build Coastguard Worker 		}
367*25da2beaSAndroid Build Coastguard Worker 
368*25da2beaSAndroid Build Coastguard Worker 		ret = test_mixed_reg(bgids[i]);
369*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
370*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_mixed_reg failed\n");
371*25da2beaSAndroid Build Coastguard Worker 			return 1;
372*25da2beaSAndroid Build Coastguard Worker 		}
373*25da2beaSAndroid Build Coastguard Worker 
374*25da2beaSAndroid Build Coastguard Worker 		ret = test_mixed_reg2(bgids[i]);
375*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
376*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_mixed_reg2 failed\n");
377*25da2beaSAndroid Build Coastguard Worker 			return 1;
378*25da2beaSAndroid Build Coastguard Worker 		}
379*25da2beaSAndroid Build Coastguard Worker 	}
380*25da2beaSAndroid Build Coastguard Worker 
381*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; !no_buf_ring && entries[i] != -1; i++) {
382*25da2beaSAndroid Build Coastguard Worker 		ret = test_running(2, entries[i], 3);
383*25da2beaSAndroid Build Coastguard Worker 		if (ret) {
384*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "test_running(%d) failed\n", entries[i]);
385*25da2beaSAndroid Build Coastguard Worker 			return 1;
386*25da2beaSAndroid Build Coastguard Worker 		}
387*25da2beaSAndroid Build Coastguard Worker 	}
388*25da2beaSAndroid Build Coastguard Worker 
389*25da2beaSAndroid Build Coastguard Worker 	return 0;
390*25da2beaSAndroid Build Coastguard Worker }
391