xref: /f-stack/dpdk/app/test/test_ring.c (revision 2d9fd380)
14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang  * Copyright(c) 2010-2014 Intel Corporation
3*2d9fd380Sjfb8856606  * Copyright(c) 2020 Arm Limited
44418919fSjohnjiang  */
54418919fSjohnjiang 
64418919fSjohnjiang #include <string.h>
74418919fSjohnjiang #include <stdarg.h>
84418919fSjohnjiang #include <stdio.h>
94418919fSjohnjiang #include <stdlib.h>
104418919fSjohnjiang #include <stdint.h>
114418919fSjohnjiang #include <inttypes.h>
124418919fSjohnjiang #include <errno.h>
134418919fSjohnjiang #include <sys/queue.h>
144418919fSjohnjiang 
154418919fSjohnjiang #include <rte_common.h>
164418919fSjohnjiang #include <rte_log.h>
174418919fSjohnjiang #include <rte_memory.h>
184418919fSjohnjiang #include <rte_launch.h>
194418919fSjohnjiang #include <rte_cycles.h>
204418919fSjohnjiang #include <rte_eal.h>
214418919fSjohnjiang #include <rte_per_lcore.h>
224418919fSjohnjiang #include <rte_lcore.h>
234418919fSjohnjiang #include <rte_atomic.h>
244418919fSjohnjiang #include <rte_branch_prediction.h>
254418919fSjohnjiang #include <rte_malloc.h>
264418919fSjohnjiang #include <rte_ring.h>
27*2d9fd380Sjfb8856606 #include <rte_ring_elem.h>
284418919fSjohnjiang #include <rte_random.h>
294418919fSjohnjiang #include <rte_errno.h>
304418919fSjohnjiang #include <rte_hexdump.h>
314418919fSjohnjiang 
324418919fSjohnjiang #include "test.h"
33*2d9fd380Sjfb8856606 #include "test_ring.h"
344418919fSjohnjiang 
354418919fSjohnjiang /*
364418919fSjohnjiang  * Ring
374418919fSjohnjiang  * ====
384418919fSjohnjiang  *
39*2d9fd380Sjfb8856606  * #. Functional tests. Tests single/bulk/burst, default/SPSC/MPMC,
40*2d9fd380Sjfb8856606  *    legacy/custom element size (4B, 8B, 16B, 20B) APIs.
41*2d9fd380Sjfb8856606  *    Some tests incorporate unaligned addresses for objects.
42*2d9fd380Sjfb8856606  *    The enqueued/dequeued data is validated for correctness.
434418919fSjohnjiang  *
44*2d9fd380Sjfb8856606  * #. Performance tests are in test_ring_perf.c
454418919fSjohnjiang  */
464418919fSjohnjiang 
474418919fSjohnjiang #define RING_SIZE 4096
484418919fSjohnjiang #define MAX_BULK 32
494418919fSjohnjiang 
50*2d9fd380Sjfb8856606 /*
51*2d9fd380Sjfb8856606  * Validate the return value of test cases and print details of the
52*2d9fd380Sjfb8856606  * ring if validation fails
53*2d9fd380Sjfb8856606  *
54*2d9fd380Sjfb8856606  * @param exp
55*2d9fd380Sjfb8856606  *   Expression to validate return value.
56*2d9fd380Sjfb8856606  * @param r
57*2d9fd380Sjfb8856606  *   A pointer to the ring structure.
58*2d9fd380Sjfb8856606  */
59*2d9fd380Sjfb8856606 #define TEST_RING_VERIFY(exp, r, errst) do {				\
604418919fSjohnjiang 	if (!(exp)) {							\
614418919fSjohnjiang 		printf("error at %s:%d\tcondition " #exp " failed\n",	\
624418919fSjohnjiang 		    __func__, __LINE__);				\
63*2d9fd380Sjfb8856606 		rte_ring_dump(stdout, (r));				\
64*2d9fd380Sjfb8856606 		errst;							\
65*2d9fd380Sjfb8856606 	}								\
66*2d9fd380Sjfb8856606 } while (0)
67*2d9fd380Sjfb8856606 
68*2d9fd380Sjfb8856606 #define TEST_RING_FULL_EMPTY_ITER	8
69*2d9fd380Sjfb8856606 
70*2d9fd380Sjfb8856606 static const int esize[] = {-1, 4, 8, 16, 20};
71*2d9fd380Sjfb8856606 
72*2d9fd380Sjfb8856606 /* Wrappers around the zero-copy APIs. The wrappers match
73*2d9fd380Sjfb8856606  * the normal enqueue/dequeue API declarations.
74*2d9fd380Sjfb8856606  */
75*2d9fd380Sjfb8856606 static unsigned int
test_ring_enqueue_zc_bulk(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)76*2d9fd380Sjfb8856606 test_ring_enqueue_zc_bulk(struct rte_ring *r, void * const *obj_table,
77*2d9fd380Sjfb8856606 	unsigned int n, unsigned int *free_space)
78*2d9fd380Sjfb8856606 {
79*2d9fd380Sjfb8856606 	uint32_t ret;
80*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
81*2d9fd380Sjfb8856606 
82*2d9fd380Sjfb8856606 	ret = rte_ring_enqueue_zc_bulk_start(r, n, &zcd, free_space);
83*2d9fd380Sjfb8856606 	if (ret != 0) {
84*2d9fd380Sjfb8856606 		/* Copy the data to the ring */
85*2d9fd380Sjfb8856606 		test_ring_copy_to(&zcd, obj_table, sizeof(void *), ret);
86*2d9fd380Sjfb8856606 		rte_ring_enqueue_zc_finish(r, ret);
874418919fSjohnjiang 	}
884418919fSjohnjiang 
89*2d9fd380Sjfb8856606 	return ret;
90*2d9fd380Sjfb8856606 }
91*2d9fd380Sjfb8856606 
92*2d9fd380Sjfb8856606 static unsigned int
test_ring_enqueue_zc_bulk_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)93*2d9fd380Sjfb8856606 test_ring_enqueue_zc_bulk_elem(struct rte_ring *r, const void *obj_table,
94*2d9fd380Sjfb8856606 	unsigned int esize, unsigned int n, unsigned int *free_space)
95*2d9fd380Sjfb8856606 {
96*2d9fd380Sjfb8856606 	unsigned int ret;
97*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
98*2d9fd380Sjfb8856606 
99*2d9fd380Sjfb8856606 	ret = rte_ring_enqueue_zc_bulk_elem_start(r, esize, n,
100*2d9fd380Sjfb8856606 				&zcd, free_space);
101*2d9fd380Sjfb8856606 	if (ret != 0) {
102*2d9fd380Sjfb8856606 		/* Copy the data to the ring */
103*2d9fd380Sjfb8856606 		test_ring_copy_to(&zcd, obj_table, esize, ret);
104*2d9fd380Sjfb8856606 		rte_ring_enqueue_zc_finish(r, ret);
105*2d9fd380Sjfb8856606 	}
106*2d9fd380Sjfb8856606 
107*2d9fd380Sjfb8856606 	return ret;
108*2d9fd380Sjfb8856606 }
109*2d9fd380Sjfb8856606 
110*2d9fd380Sjfb8856606 static unsigned int
test_ring_enqueue_zc_burst(struct rte_ring * r,void * const * obj_table,unsigned int n,unsigned int * free_space)111*2d9fd380Sjfb8856606 test_ring_enqueue_zc_burst(struct rte_ring *r, void * const *obj_table,
112*2d9fd380Sjfb8856606 	unsigned int n, unsigned int *free_space)
113*2d9fd380Sjfb8856606 {
114*2d9fd380Sjfb8856606 	unsigned int ret;
115*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
116*2d9fd380Sjfb8856606 
117*2d9fd380Sjfb8856606 	ret = rte_ring_enqueue_zc_burst_start(r, n, &zcd, free_space);
118*2d9fd380Sjfb8856606 	if (ret != 0) {
119*2d9fd380Sjfb8856606 		/* Copy the data to the ring */
120*2d9fd380Sjfb8856606 		test_ring_copy_to(&zcd, obj_table, sizeof(void *), ret);
121*2d9fd380Sjfb8856606 		rte_ring_enqueue_zc_finish(r, ret);
122*2d9fd380Sjfb8856606 	}
123*2d9fd380Sjfb8856606 
124*2d9fd380Sjfb8856606 	return ret;
125*2d9fd380Sjfb8856606 }
126*2d9fd380Sjfb8856606 
127*2d9fd380Sjfb8856606 static unsigned int
test_ring_enqueue_zc_burst_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)128*2d9fd380Sjfb8856606 test_ring_enqueue_zc_burst_elem(struct rte_ring *r, const void *obj_table,
129*2d9fd380Sjfb8856606 	unsigned int esize, unsigned int n, unsigned int *free_space)
130*2d9fd380Sjfb8856606 {
131*2d9fd380Sjfb8856606 	unsigned int ret;
132*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
133*2d9fd380Sjfb8856606 
134*2d9fd380Sjfb8856606 	ret = rte_ring_enqueue_zc_burst_elem_start(r, esize, n,
135*2d9fd380Sjfb8856606 				&zcd, free_space);
136*2d9fd380Sjfb8856606 	if (ret != 0) {
137*2d9fd380Sjfb8856606 		/* Copy the data to the ring */
138*2d9fd380Sjfb8856606 		test_ring_copy_to(&zcd, obj_table, esize, ret);
139*2d9fd380Sjfb8856606 		rte_ring_enqueue_zc_finish(r, ret);
140*2d9fd380Sjfb8856606 	}
141*2d9fd380Sjfb8856606 
142*2d9fd380Sjfb8856606 	return ret;
143*2d9fd380Sjfb8856606 }
144*2d9fd380Sjfb8856606 
145*2d9fd380Sjfb8856606 static unsigned int
test_ring_dequeue_zc_bulk(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)146*2d9fd380Sjfb8856606 test_ring_dequeue_zc_bulk(struct rte_ring *r, void **obj_table,
147*2d9fd380Sjfb8856606 	unsigned int n, unsigned int *available)
148*2d9fd380Sjfb8856606 {
149*2d9fd380Sjfb8856606 	unsigned int ret;
150*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
151*2d9fd380Sjfb8856606 
152*2d9fd380Sjfb8856606 	ret = rte_ring_dequeue_zc_bulk_start(r, n, &zcd, available);
153*2d9fd380Sjfb8856606 	if (ret != 0) {
154*2d9fd380Sjfb8856606 		/* Copy the data from the ring */
155*2d9fd380Sjfb8856606 		test_ring_copy_from(&zcd, obj_table, sizeof(void *), ret);
156*2d9fd380Sjfb8856606 		rte_ring_dequeue_zc_finish(r, ret);
157*2d9fd380Sjfb8856606 	}
158*2d9fd380Sjfb8856606 
159*2d9fd380Sjfb8856606 	return ret;
160*2d9fd380Sjfb8856606 }
161*2d9fd380Sjfb8856606 
162*2d9fd380Sjfb8856606 static unsigned int
test_ring_dequeue_zc_bulk_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)163*2d9fd380Sjfb8856606 test_ring_dequeue_zc_bulk_elem(struct rte_ring *r, void *obj_table,
164*2d9fd380Sjfb8856606 	unsigned int esize, unsigned int n, unsigned int *available)
165*2d9fd380Sjfb8856606 {
166*2d9fd380Sjfb8856606 	unsigned int ret;
167*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
168*2d9fd380Sjfb8856606 
169*2d9fd380Sjfb8856606 	ret = rte_ring_dequeue_zc_bulk_elem_start(r, esize, n,
170*2d9fd380Sjfb8856606 				&zcd, available);
171*2d9fd380Sjfb8856606 	if (ret != 0) {
172*2d9fd380Sjfb8856606 		/* Copy the data from the ring */
173*2d9fd380Sjfb8856606 		test_ring_copy_from(&zcd, obj_table, esize, ret);
174*2d9fd380Sjfb8856606 		rte_ring_dequeue_zc_finish(r, ret);
175*2d9fd380Sjfb8856606 	}
176*2d9fd380Sjfb8856606 
177*2d9fd380Sjfb8856606 	return ret;
178*2d9fd380Sjfb8856606 }
179*2d9fd380Sjfb8856606 
180*2d9fd380Sjfb8856606 static unsigned int
test_ring_dequeue_zc_burst(struct rte_ring * r,void ** obj_table,unsigned int n,unsigned int * available)181*2d9fd380Sjfb8856606 test_ring_dequeue_zc_burst(struct rte_ring *r, void **obj_table,
182*2d9fd380Sjfb8856606 	unsigned int n, unsigned int *available)
183*2d9fd380Sjfb8856606 {
184*2d9fd380Sjfb8856606 	unsigned int ret;
185*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
186*2d9fd380Sjfb8856606 
187*2d9fd380Sjfb8856606 	ret = rte_ring_dequeue_zc_burst_start(r, n, &zcd, available);
188*2d9fd380Sjfb8856606 	if (ret != 0) {
189*2d9fd380Sjfb8856606 		/* Copy the data from the ring */
190*2d9fd380Sjfb8856606 		test_ring_copy_from(&zcd, obj_table, sizeof(void *), ret);
191*2d9fd380Sjfb8856606 		rte_ring_dequeue_zc_finish(r, ret);
192*2d9fd380Sjfb8856606 	}
193*2d9fd380Sjfb8856606 
194*2d9fd380Sjfb8856606 	return ret;
195*2d9fd380Sjfb8856606 }
196*2d9fd380Sjfb8856606 
197*2d9fd380Sjfb8856606 static unsigned int
test_ring_dequeue_zc_burst_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)198*2d9fd380Sjfb8856606 test_ring_dequeue_zc_burst_elem(struct rte_ring *r, void *obj_table,
199*2d9fd380Sjfb8856606 	unsigned int esize, unsigned int n, unsigned int *available)
200*2d9fd380Sjfb8856606 {
201*2d9fd380Sjfb8856606 	unsigned int ret;
202*2d9fd380Sjfb8856606 	struct rte_ring_zc_data zcd;
203*2d9fd380Sjfb8856606 
204*2d9fd380Sjfb8856606 	ret = rte_ring_dequeue_zc_burst_elem_start(r, esize, n,
205*2d9fd380Sjfb8856606 				&zcd, available);
206*2d9fd380Sjfb8856606 	if (ret != 0) {
207*2d9fd380Sjfb8856606 		/* Copy the data from the ring */
208*2d9fd380Sjfb8856606 		test_ring_copy_from(&zcd, obj_table, esize, ret);
209*2d9fd380Sjfb8856606 		rte_ring_dequeue_zc_finish(r, ret);
210*2d9fd380Sjfb8856606 	}
211*2d9fd380Sjfb8856606 
212*2d9fd380Sjfb8856606 	return ret;
213*2d9fd380Sjfb8856606 }
214*2d9fd380Sjfb8856606 
215*2d9fd380Sjfb8856606 static const struct {
216*2d9fd380Sjfb8856606 	const char *desc;
217*2d9fd380Sjfb8856606 	uint32_t api_type;
218*2d9fd380Sjfb8856606 	uint32_t create_flags;
219*2d9fd380Sjfb8856606 	struct {
220*2d9fd380Sjfb8856606 		unsigned int (*flegacy)(struct rte_ring *r,
221*2d9fd380Sjfb8856606 			void * const *obj_table, unsigned int n,
222*2d9fd380Sjfb8856606 			unsigned int *free_space);
223*2d9fd380Sjfb8856606 		unsigned int (*felem)(struct rte_ring *r, const void *obj_table,
224*2d9fd380Sjfb8856606 			unsigned int esize, unsigned int n,
225*2d9fd380Sjfb8856606 			unsigned int *free_space);
226*2d9fd380Sjfb8856606 	} enq;
227*2d9fd380Sjfb8856606 	struct {
228*2d9fd380Sjfb8856606 		unsigned int (*flegacy)(struct rte_ring *r,
229*2d9fd380Sjfb8856606 			void **obj_table, unsigned int n,
230*2d9fd380Sjfb8856606 			unsigned int *available);
231*2d9fd380Sjfb8856606 		unsigned int (*felem)(struct rte_ring *r, void *obj_table,
232*2d9fd380Sjfb8856606 			unsigned int esize, unsigned int n,
233*2d9fd380Sjfb8856606 			unsigned int *available);
234*2d9fd380Sjfb8856606 	} deq;
235*2d9fd380Sjfb8856606 } test_enqdeq_impl[] = {
236*2d9fd380Sjfb8856606 	{
237*2d9fd380Sjfb8856606 		.desc = "MP/MC sync mode",
238*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
239*2d9fd380Sjfb8856606 		.create_flags = 0,
240*2d9fd380Sjfb8856606 		.enq = {
241*2d9fd380Sjfb8856606 			.flegacy = rte_ring_enqueue_bulk,
242*2d9fd380Sjfb8856606 			.felem = rte_ring_enqueue_bulk_elem,
243*2d9fd380Sjfb8856606 		},
244*2d9fd380Sjfb8856606 		.deq = {
245*2d9fd380Sjfb8856606 			.flegacy = rte_ring_dequeue_bulk,
246*2d9fd380Sjfb8856606 			.felem = rte_ring_dequeue_bulk_elem,
247*2d9fd380Sjfb8856606 		},
248*2d9fd380Sjfb8856606 	},
249*2d9fd380Sjfb8856606 	{
250*2d9fd380Sjfb8856606 		.desc = "SP/SC sync mode",
251*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_SPSC,
252*2d9fd380Sjfb8856606 		.create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
253*2d9fd380Sjfb8856606 		.enq = {
254*2d9fd380Sjfb8856606 			.flegacy = rte_ring_sp_enqueue_bulk,
255*2d9fd380Sjfb8856606 			.felem = rte_ring_sp_enqueue_bulk_elem,
256*2d9fd380Sjfb8856606 		},
257*2d9fd380Sjfb8856606 		.deq = {
258*2d9fd380Sjfb8856606 			.flegacy = rte_ring_sc_dequeue_bulk,
259*2d9fd380Sjfb8856606 			.felem = rte_ring_sc_dequeue_bulk_elem,
260*2d9fd380Sjfb8856606 		},
261*2d9fd380Sjfb8856606 	},
262*2d9fd380Sjfb8856606 	{
263*2d9fd380Sjfb8856606 		.desc = "MP/MC sync mode",
264*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_MPMC,
265*2d9fd380Sjfb8856606 		.create_flags = 0,
266*2d9fd380Sjfb8856606 		.enq = {
267*2d9fd380Sjfb8856606 			.flegacy = rte_ring_mp_enqueue_bulk,
268*2d9fd380Sjfb8856606 			.felem = rte_ring_mp_enqueue_bulk_elem,
269*2d9fd380Sjfb8856606 		},
270*2d9fd380Sjfb8856606 		.deq = {
271*2d9fd380Sjfb8856606 			.flegacy = rte_ring_mc_dequeue_bulk,
272*2d9fd380Sjfb8856606 			.felem = rte_ring_mc_dequeue_bulk_elem,
273*2d9fd380Sjfb8856606 		},
274*2d9fd380Sjfb8856606 	},
275*2d9fd380Sjfb8856606 	{
276*2d9fd380Sjfb8856606 		.desc = "MP_RTS/MC_RTS sync mode",
277*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
278*2d9fd380Sjfb8856606 		.create_flags = RING_F_MP_RTS_ENQ | RING_F_MC_RTS_DEQ,
279*2d9fd380Sjfb8856606 		.enq = {
280*2d9fd380Sjfb8856606 			.flegacy = rte_ring_enqueue_bulk,
281*2d9fd380Sjfb8856606 			.felem = rte_ring_enqueue_bulk_elem,
282*2d9fd380Sjfb8856606 		},
283*2d9fd380Sjfb8856606 		.deq = {
284*2d9fd380Sjfb8856606 			.flegacy = rte_ring_dequeue_bulk,
285*2d9fd380Sjfb8856606 			.felem = rte_ring_dequeue_bulk_elem,
286*2d9fd380Sjfb8856606 		},
287*2d9fd380Sjfb8856606 	},
288*2d9fd380Sjfb8856606 	{
289*2d9fd380Sjfb8856606 		.desc = "MP_HTS/MC_HTS sync mode",
290*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
291*2d9fd380Sjfb8856606 		.create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
292*2d9fd380Sjfb8856606 		.enq = {
293*2d9fd380Sjfb8856606 			.flegacy = rte_ring_enqueue_bulk,
294*2d9fd380Sjfb8856606 			.felem = rte_ring_enqueue_bulk_elem,
295*2d9fd380Sjfb8856606 		},
296*2d9fd380Sjfb8856606 		.deq = {
297*2d9fd380Sjfb8856606 			.flegacy = rte_ring_dequeue_bulk,
298*2d9fd380Sjfb8856606 			.felem = rte_ring_dequeue_bulk_elem,
299*2d9fd380Sjfb8856606 		},
300*2d9fd380Sjfb8856606 	},
301*2d9fd380Sjfb8856606 	{
302*2d9fd380Sjfb8856606 		.desc = "MP/MC sync mode",
303*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
304*2d9fd380Sjfb8856606 		.create_flags = 0,
305*2d9fd380Sjfb8856606 		.enq = {
306*2d9fd380Sjfb8856606 			.flegacy = rte_ring_enqueue_burst,
307*2d9fd380Sjfb8856606 			.felem = rte_ring_enqueue_burst_elem,
308*2d9fd380Sjfb8856606 		},
309*2d9fd380Sjfb8856606 		.deq = {
310*2d9fd380Sjfb8856606 			.flegacy = rte_ring_dequeue_burst,
311*2d9fd380Sjfb8856606 			.felem = rte_ring_dequeue_burst_elem,
312*2d9fd380Sjfb8856606 		},
313*2d9fd380Sjfb8856606 	},
314*2d9fd380Sjfb8856606 	{
315*2d9fd380Sjfb8856606 		.desc = "SP/SC sync mode",
316*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_SPSC,
317*2d9fd380Sjfb8856606 		.create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
318*2d9fd380Sjfb8856606 		.enq = {
319*2d9fd380Sjfb8856606 			.flegacy = rte_ring_sp_enqueue_burst,
320*2d9fd380Sjfb8856606 			.felem = rte_ring_sp_enqueue_burst_elem,
321*2d9fd380Sjfb8856606 		},
322*2d9fd380Sjfb8856606 		.deq = {
323*2d9fd380Sjfb8856606 			.flegacy = rte_ring_sc_dequeue_burst,
324*2d9fd380Sjfb8856606 			.felem = rte_ring_sc_dequeue_burst_elem,
325*2d9fd380Sjfb8856606 		},
326*2d9fd380Sjfb8856606 	},
327*2d9fd380Sjfb8856606 	{
328*2d9fd380Sjfb8856606 		.desc = "MP/MC sync mode",
329*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_MPMC,
330*2d9fd380Sjfb8856606 		.create_flags = 0,
331*2d9fd380Sjfb8856606 		.enq = {
332*2d9fd380Sjfb8856606 			.flegacy = rte_ring_mp_enqueue_burst,
333*2d9fd380Sjfb8856606 			.felem = rte_ring_mp_enqueue_burst_elem,
334*2d9fd380Sjfb8856606 		},
335*2d9fd380Sjfb8856606 		.deq = {
336*2d9fd380Sjfb8856606 			.flegacy = rte_ring_mc_dequeue_burst,
337*2d9fd380Sjfb8856606 			.felem = rte_ring_mc_dequeue_burst_elem,
338*2d9fd380Sjfb8856606 		},
339*2d9fd380Sjfb8856606 	},
340*2d9fd380Sjfb8856606 	{
341*2d9fd380Sjfb8856606 		.desc = "MP_RTS/MC_RTS sync mode",
342*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
343*2d9fd380Sjfb8856606 		.create_flags = RING_F_MP_RTS_ENQ | RING_F_MC_RTS_DEQ,
344*2d9fd380Sjfb8856606 		.enq = {
345*2d9fd380Sjfb8856606 			.flegacy = rte_ring_enqueue_burst,
346*2d9fd380Sjfb8856606 			.felem = rte_ring_enqueue_burst_elem,
347*2d9fd380Sjfb8856606 		},
348*2d9fd380Sjfb8856606 		.deq = {
349*2d9fd380Sjfb8856606 			.flegacy = rte_ring_dequeue_burst,
350*2d9fd380Sjfb8856606 			.felem = rte_ring_dequeue_burst_elem,
351*2d9fd380Sjfb8856606 		},
352*2d9fd380Sjfb8856606 	},
353*2d9fd380Sjfb8856606 	{
354*2d9fd380Sjfb8856606 		.desc = "MP_HTS/MC_HTS sync mode",
355*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
356*2d9fd380Sjfb8856606 		.create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
357*2d9fd380Sjfb8856606 		.enq = {
358*2d9fd380Sjfb8856606 			.flegacy = rte_ring_enqueue_burst,
359*2d9fd380Sjfb8856606 			.felem = rte_ring_enqueue_burst_elem,
360*2d9fd380Sjfb8856606 		},
361*2d9fd380Sjfb8856606 		.deq = {
362*2d9fd380Sjfb8856606 			.flegacy = rte_ring_dequeue_burst,
363*2d9fd380Sjfb8856606 			.felem = rte_ring_dequeue_burst_elem,
364*2d9fd380Sjfb8856606 		},
365*2d9fd380Sjfb8856606 	},
366*2d9fd380Sjfb8856606 	{
367*2d9fd380Sjfb8856606 		.desc = "SP/SC sync mode (ZC)",
368*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_SPSC,
369*2d9fd380Sjfb8856606 		.create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
370*2d9fd380Sjfb8856606 		.enq = {
371*2d9fd380Sjfb8856606 			.flegacy = test_ring_enqueue_zc_bulk,
372*2d9fd380Sjfb8856606 			.felem = test_ring_enqueue_zc_bulk_elem,
373*2d9fd380Sjfb8856606 		},
374*2d9fd380Sjfb8856606 		.deq = {
375*2d9fd380Sjfb8856606 			.flegacy = test_ring_dequeue_zc_bulk,
376*2d9fd380Sjfb8856606 			.felem = test_ring_dequeue_zc_bulk_elem,
377*2d9fd380Sjfb8856606 		},
378*2d9fd380Sjfb8856606 	},
379*2d9fd380Sjfb8856606 	{
380*2d9fd380Sjfb8856606 		.desc = "MP_HTS/MC_HTS sync mode (ZC)",
381*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BULK | TEST_RING_THREAD_DEF,
382*2d9fd380Sjfb8856606 		.create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
383*2d9fd380Sjfb8856606 		.enq = {
384*2d9fd380Sjfb8856606 			.flegacy = test_ring_enqueue_zc_bulk,
385*2d9fd380Sjfb8856606 			.felem = test_ring_enqueue_zc_bulk_elem,
386*2d9fd380Sjfb8856606 		},
387*2d9fd380Sjfb8856606 		.deq = {
388*2d9fd380Sjfb8856606 			.flegacy = test_ring_dequeue_zc_bulk,
389*2d9fd380Sjfb8856606 			.felem = test_ring_dequeue_zc_bulk_elem,
390*2d9fd380Sjfb8856606 		},
391*2d9fd380Sjfb8856606 	},
392*2d9fd380Sjfb8856606 	{
393*2d9fd380Sjfb8856606 		.desc = "SP/SC sync mode (ZC)",
394*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_SPSC,
395*2d9fd380Sjfb8856606 		.create_flags = RING_F_SP_ENQ | RING_F_SC_DEQ,
396*2d9fd380Sjfb8856606 		.enq = {
397*2d9fd380Sjfb8856606 			.flegacy = test_ring_enqueue_zc_burst,
398*2d9fd380Sjfb8856606 			.felem = test_ring_enqueue_zc_burst_elem,
399*2d9fd380Sjfb8856606 		},
400*2d9fd380Sjfb8856606 		.deq = {
401*2d9fd380Sjfb8856606 			.flegacy = test_ring_dequeue_zc_burst,
402*2d9fd380Sjfb8856606 			.felem = test_ring_dequeue_zc_burst_elem,
403*2d9fd380Sjfb8856606 		},
404*2d9fd380Sjfb8856606 	},
405*2d9fd380Sjfb8856606 	{
406*2d9fd380Sjfb8856606 		.desc = "MP_HTS/MC_HTS sync mode (ZC)",
407*2d9fd380Sjfb8856606 		.api_type = TEST_RING_ELEM_BURST | TEST_RING_THREAD_DEF,
408*2d9fd380Sjfb8856606 		.create_flags = RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ,
409*2d9fd380Sjfb8856606 		.enq = {
410*2d9fd380Sjfb8856606 			.flegacy = test_ring_enqueue_zc_burst,
411*2d9fd380Sjfb8856606 			.felem = test_ring_enqueue_zc_burst_elem,
412*2d9fd380Sjfb8856606 		},
413*2d9fd380Sjfb8856606 		.deq = {
414*2d9fd380Sjfb8856606 			.flegacy = test_ring_dequeue_zc_burst,
415*2d9fd380Sjfb8856606 			.felem = test_ring_dequeue_zc_burst_elem,
416*2d9fd380Sjfb8856606 		},
417*2d9fd380Sjfb8856606 	}
418*2d9fd380Sjfb8856606 };
419*2d9fd380Sjfb8856606 
420*2d9fd380Sjfb8856606 static unsigned int
test_ring_enq_impl(struct rte_ring * r,void ** obj,int esize,unsigned int n,unsigned int test_idx)421*2d9fd380Sjfb8856606 test_ring_enq_impl(struct rte_ring *r, void **obj, int esize, unsigned int n,
422*2d9fd380Sjfb8856606 	unsigned int test_idx)
423*2d9fd380Sjfb8856606 {
424*2d9fd380Sjfb8856606 	if (esize == -1)
425*2d9fd380Sjfb8856606 		return test_enqdeq_impl[test_idx].enq.flegacy(r, obj, n, NULL);
426*2d9fd380Sjfb8856606 	else
427*2d9fd380Sjfb8856606 		return test_enqdeq_impl[test_idx].enq.felem(r, obj, esize, n,
428*2d9fd380Sjfb8856606 			NULL);
429*2d9fd380Sjfb8856606 }
430*2d9fd380Sjfb8856606 
431*2d9fd380Sjfb8856606 static unsigned int
test_ring_deq_impl(struct rte_ring * r,void ** obj,int esize,unsigned int n,unsigned int test_idx)432*2d9fd380Sjfb8856606 test_ring_deq_impl(struct rte_ring *r, void **obj, int esize, unsigned int n,
433*2d9fd380Sjfb8856606 	unsigned int test_idx)
434*2d9fd380Sjfb8856606 {
435*2d9fd380Sjfb8856606 	if (esize == -1)
436*2d9fd380Sjfb8856606 		return test_enqdeq_impl[test_idx].deq.flegacy(r, obj, n, NULL);
437*2d9fd380Sjfb8856606 	else
438*2d9fd380Sjfb8856606 		return test_enqdeq_impl[test_idx].deq.felem(r, obj, esize, n,
439*2d9fd380Sjfb8856606 			NULL);
440*2d9fd380Sjfb8856606 }
441*2d9fd380Sjfb8856606 
442*2d9fd380Sjfb8856606 static void
test_ring_mem_init(void * obj,unsigned int count,int esize)443*2d9fd380Sjfb8856606 test_ring_mem_init(void *obj, unsigned int count, int esize)
444*2d9fd380Sjfb8856606 {
445*2d9fd380Sjfb8856606 	unsigned int i;
446*2d9fd380Sjfb8856606 
447*2d9fd380Sjfb8856606 	/* Legacy queue APIs? */
448*2d9fd380Sjfb8856606 	if (esize == -1)
449*2d9fd380Sjfb8856606 		for (i = 0; i < count; i++)
450*2d9fd380Sjfb8856606 			((void **)obj)[i] = (void *)(uintptr_t)i;
451*2d9fd380Sjfb8856606 	else
452*2d9fd380Sjfb8856606 		for (i = 0; i < (count * esize / sizeof(uint32_t)); i++)
453*2d9fd380Sjfb8856606 			((uint32_t *)obj)[i] = i;
454*2d9fd380Sjfb8856606 }
455*2d9fd380Sjfb8856606 
456*2d9fd380Sjfb8856606 static int
test_ring_mem_cmp(void * src,void * dst,unsigned int size)457*2d9fd380Sjfb8856606 test_ring_mem_cmp(void *src, void *dst, unsigned int size)
458*2d9fd380Sjfb8856606 {
459*2d9fd380Sjfb8856606 	int ret;
460*2d9fd380Sjfb8856606 
461*2d9fd380Sjfb8856606 	ret = memcmp(src, dst, size);
462*2d9fd380Sjfb8856606 	if (ret) {
463*2d9fd380Sjfb8856606 		rte_hexdump(stdout, "src", src, size);
464*2d9fd380Sjfb8856606 		rte_hexdump(stdout, "dst", dst, size);
465*2d9fd380Sjfb8856606 		printf("data after dequeue is not the same\n");
466*2d9fd380Sjfb8856606 	}
467*2d9fd380Sjfb8856606 
468*2d9fd380Sjfb8856606 	return ret;
469*2d9fd380Sjfb8856606 }
470*2d9fd380Sjfb8856606 
471*2d9fd380Sjfb8856606 static void
test_ring_print_test_string(const char * istr,unsigned int api_type,int esize)472*2d9fd380Sjfb8856606 test_ring_print_test_string(const char *istr, unsigned int api_type, int esize)
473*2d9fd380Sjfb8856606 {
474*2d9fd380Sjfb8856606 	printf("\n%s: ", istr);
475*2d9fd380Sjfb8856606 
476*2d9fd380Sjfb8856606 	if (esize == -1)
477*2d9fd380Sjfb8856606 		printf("legacy APIs: ");
478*2d9fd380Sjfb8856606 	else
479*2d9fd380Sjfb8856606 		printf("elem APIs: element size %dB ", esize);
480*2d9fd380Sjfb8856606 
481*2d9fd380Sjfb8856606 	if (api_type == TEST_RING_IGNORE_API_TYPE)
482*2d9fd380Sjfb8856606 		return;
483*2d9fd380Sjfb8856606 
484*2d9fd380Sjfb8856606 	if (api_type & TEST_RING_THREAD_DEF)
485*2d9fd380Sjfb8856606 		printf(": default enqueue/dequeue: ");
486*2d9fd380Sjfb8856606 	else if (api_type & TEST_RING_THREAD_SPSC)
487*2d9fd380Sjfb8856606 		printf(": SP/SC: ");
488*2d9fd380Sjfb8856606 	else if (api_type & TEST_RING_THREAD_MPMC)
489*2d9fd380Sjfb8856606 		printf(": MP/MC: ");
490*2d9fd380Sjfb8856606 
491*2d9fd380Sjfb8856606 	if (api_type & TEST_RING_ELEM_SINGLE)
492*2d9fd380Sjfb8856606 		printf("single\n");
493*2d9fd380Sjfb8856606 	else if (api_type & TEST_RING_ELEM_BULK)
494*2d9fd380Sjfb8856606 		printf("bulk\n");
495*2d9fd380Sjfb8856606 	else if (api_type & TEST_RING_ELEM_BURST)
496*2d9fd380Sjfb8856606 		printf("burst\n");
497*2d9fd380Sjfb8856606 }
4984418919fSjohnjiang 
4994418919fSjohnjiang /*
500*2d9fd380Sjfb8856606  * Various negative test cases.
5014418919fSjohnjiang  */
5024418919fSjohnjiang static int
test_ring_negative_tests(void)503*2d9fd380Sjfb8856606 test_ring_negative_tests(void)
5044418919fSjohnjiang {
505*2d9fd380Sjfb8856606 	struct rte_ring *rp = NULL;
506*2d9fd380Sjfb8856606 	struct rte_ring *rt = NULL;
507*2d9fd380Sjfb8856606 	unsigned int i;
5084418919fSjohnjiang 
509*2d9fd380Sjfb8856606 	/* Test with esize not a multiple of 4 */
510*2d9fd380Sjfb8856606 	rp = test_ring_create("test_bad_element_size", 23,
511*2d9fd380Sjfb8856606 				RING_SIZE + 1, SOCKET_ID_ANY, 0);
512*2d9fd380Sjfb8856606 	if (rp != NULL) {
513*2d9fd380Sjfb8856606 		printf("Test failed to detect invalid element size\n");
514*2d9fd380Sjfb8856606 		goto test_fail;
515*2d9fd380Sjfb8856606 	}
5164418919fSjohnjiang 
5174418919fSjohnjiang 
518*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
519*2d9fd380Sjfb8856606 		/* Test if ring size is not power of 2 */
520*2d9fd380Sjfb8856606 		rp = test_ring_create("test_bad_ring_size", esize[i],
521*2d9fd380Sjfb8856606 					RING_SIZE + 1, SOCKET_ID_ANY, 0);
522*2d9fd380Sjfb8856606 		if (rp != NULL) {
523*2d9fd380Sjfb8856606 			printf("Test failed to detect odd count\n");
524*2d9fd380Sjfb8856606 			goto test_fail;
525*2d9fd380Sjfb8856606 		}
526*2d9fd380Sjfb8856606 
527*2d9fd380Sjfb8856606 		/* Test if ring size is exceeding the limit */
528*2d9fd380Sjfb8856606 		rp = test_ring_create("test_bad_ring_size", esize[i],
529*2d9fd380Sjfb8856606 					RTE_RING_SZ_MASK + 1, SOCKET_ID_ANY, 0);
530*2d9fd380Sjfb8856606 		if (rp != NULL) {
531*2d9fd380Sjfb8856606 			printf("Test failed to detect limits\n");
532*2d9fd380Sjfb8856606 			goto test_fail;
533*2d9fd380Sjfb8856606 		}
534*2d9fd380Sjfb8856606 
535*2d9fd380Sjfb8856606 		/* Tests if lookup returns NULL on non-existing ring */
536*2d9fd380Sjfb8856606 		rp = rte_ring_lookup("ring_not_found");
537*2d9fd380Sjfb8856606 		if (rp != NULL && rte_errno != ENOENT) {
538*2d9fd380Sjfb8856606 			printf("Test failed to detect NULL ring lookup\n");
539*2d9fd380Sjfb8856606 			goto test_fail;
540*2d9fd380Sjfb8856606 		}
541*2d9fd380Sjfb8856606 
542*2d9fd380Sjfb8856606 		/* Test to if a non-power of 2 count causes the create
543*2d9fd380Sjfb8856606 		 * function to fail correctly
544*2d9fd380Sjfb8856606 		 */
545*2d9fd380Sjfb8856606 		rp = test_ring_create("test_ring_count", esize[i], 4097,
546*2d9fd380Sjfb8856606 					SOCKET_ID_ANY, 0);
547*2d9fd380Sjfb8856606 		if (rp != NULL)
548*2d9fd380Sjfb8856606 			goto test_fail;
549*2d9fd380Sjfb8856606 
550*2d9fd380Sjfb8856606 		rp = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
551*2d9fd380Sjfb8856606 					SOCKET_ID_ANY,
552*2d9fd380Sjfb8856606 					RING_F_SP_ENQ | RING_F_SC_DEQ);
553*2d9fd380Sjfb8856606 		if (rp == NULL) {
554*2d9fd380Sjfb8856606 			printf("test_ring_negative fail to create ring\n");
555*2d9fd380Sjfb8856606 			goto test_fail;
556*2d9fd380Sjfb8856606 		}
557*2d9fd380Sjfb8856606 
558*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_lookup("test_ring_negative") == rp,
559*2d9fd380Sjfb8856606 					rp, goto test_fail);
560*2d9fd380Sjfb8856606 
561*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_empty(rp) == 1, rp, goto test_fail);
562*2d9fd380Sjfb8856606 
563*2d9fd380Sjfb8856606 		/* Tests if it would always fail to create ring with an used
564*2d9fd380Sjfb8856606 		 * ring name.
565*2d9fd380Sjfb8856606 		 */
566*2d9fd380Sjfb8856606 		rt = test_ring_create("test_ring_negative", esize[i], RING_SIZE,
567*2d9fd380Sjfb8856606 					SOCKET_ID_ANY, 0);
568*2d9fd380Sjfb8856606 		if (rt != NULL)
569*2d9fd380Sjfb8856606 			goto test_fail;
570*2d9fd380Sjfb8856606 
571*2d9fd380Sjfb8856606 		rte_ring_free(rp);
572*2d9fd380Sjfb8856606 		rp = NULL;
573*2d9fd380Sjfb8856606 	}
574*2d9fd380Sjfb8856606 
575*2d9fd380Sjfb8856606 	return 0;
576*2d9fd380Sjfb8856606 
577*2d9fd380Sjfb8856606 test_fail:
578*2d9fd380Sjfb8856606 
579*2d9fd380Sjfb8856606 	rte_ring_free(rp);
580*2d9fd380Sjfb8856606 	return -1;
581*2d9fd380Sjfb8856606 }
582*2d9fd380Sjfb8856606 
583*2d9fd380Sjfb8856606 /*
584*2d9fd380Sjfb8856606  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
585*2d9fd380Sjfb8856606  * Random number of elements are enqueued and dequeued.
586*2d9fd380Sjfb8856606  */
587*2d9fd380Sjfb8856606 static int
test_ring_burst_bulk_tests1(unsigned int test_idx)588*2d9fd380Sjfb8856606 test_ring_burst_bulk_tests1(unsigned int test_idx)
589*2d9fd380Sjfb8856606 {
590*2d9fd380Sjfb8856606 	struct rte_ring *r;
591*2d9fd380Sjfb8856606 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
592*2d9fd380Sjfb8856606 	int ret;
593*2d9fd380Sjfb8856606 	unsigned int i, j, temp_sz;
594*2d9fd380Sjfb8856606 	int rand;
595*2d9fd380Sjfb8856606 	const unsigned int rsz = RING_SIZE - 1;
596*2d9fd380Sjfb8856606 
597*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
598*2d9fd380Sjfb8856606 		test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
599*2d9fd380Sjfb8856606 			test_enqdeq_impl[test_idx].api_type, esize[i]);
600*2d9fd380Sjfb8856606 
601*2d9fd380Sjfb8856606 		/* Create the ring */
602*2d9fd380Sjfb8856606 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
603*2d9fd380Sjfb8856606 				RING_SIZE, SOCKET_ID_ANY,
604*2d9fd380Sjfb8856606 				test_enqdeq_impl[test_idx].create_flags);
605*2d9fd380Sjfb8856606 
606*2d9fd380Sjfb8856606 		/* alloc dummy object pointers */
607*2d9fd380Sjfb8856606 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
608*2d9fd380Sjfb8856606 		if (src == NULL)
609*2d9fd380Sjfb8856606 			goto fail;
610*2d9fd380Sjfb8856606 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
611*2d9fd380Sjfb8856606 		cur_src = src;
612*2d9fd380Sjfb8856606 
613*2d9fd380Sjfb8856606 		/* alloc some room for copied objects */
614*2d9fd380Sjfb8856606 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
615*2d9fd380Sjfb8856606 		if (dst == NULL)
616*2d9fd380Sjfb8856606 			goto fail;
617*2d9fd380Sjfb8856606 		cur_dst = dst;
618*2d9fd380Sjfb8856606 
619*2d9fd380Sjfb8856606 		printf("Random full/empty test\n");
620*2d9fd380Sjfb8856606 
621*2d9fd380Sjfb8856606 		for (j = 0; j != TEST_RING_FULL_EMPTY_ITER; j++) {
6224418919fSjohnjiang 			/* random shift in the ring */
6234418919fSjohnjiang 			rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
6244418919fSjohnjiang 			printf("%s: iteration %u, random shift: %u;\n",
6254418919fSjohnjiang 			    __func__, i, rand);
626*2d9fd380Sjfb8856606 			ret = test_ring_enq_impl(r, cur_src, esize[i], rand,
627*2d9fd380Sjfb8856606 							test_idx);
628*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret != 0, r, goto fail);
629*2d9fd380Sjfb8856606 
630*2d9fd380Sjfb8856606 			ret = test_ring_deq_impl(r, cur_dst, esize[i], rand,
631*2d9fd380Sjfb8856606 							test_idx);
632*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == rand, r, goto fail);
6334418919fSjohnjiang 
6344418919fSjohnjiang 			/* fill the ring */
635*2d9fd380Sjfb8856606 			ret = test_ring_enq_impl(r, cur_src, esize[i], rsz,
636*2d9fd380Sjfb8856606 							test_idx);
637*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret != 0, r, goto fail);
638*2d9fd380Sjfb8856606 
639*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rte_ring_free_count(r) == 0, r, goto fail);
640*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rsz == rte_ring_count(r), r, goto fail);
641*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rte_ring_full(r), r, goto fail);
642*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rte_ring_empty(r) == 0, r, goto fail);
6434418919fSjohnjiang 
6444418919fSjohnjiang 			/* empty the ring */
645*2d9fd380Sjfb8856606 			ret = test_ring_deq_impl(r, cur_dst, esize[i], rsz,
646*2d9fd380Sjfb8856606 							test_idx);
647*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == (int)rsz, r, goto fail);
648*2d9fd380Sjfb8856606 
649*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rsz == rte_ring_free_count(r), r, goto fail);
650*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rte_ring_count(r) == 0, r, goto fail);
651*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rte_ring_full(r) == 0, r, goto fail);
652*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(rte_ring_empty(r), r, goto fail);
6534418919fSjohnjiang 
6544418919fSjohnjiang 			/* check data */
655*2d9fd380Sjfb8856606 			temp_sz = rsz * sizeof(void *);
656*2d9fd380Sjfb8856606 			if (esize[i] != -1)
657*2d9fd380Sjfb8856606 				temp_sz = rsz * esize[i];
658*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
659*2d9fd380Sjfb8856606 						temp_sz) == 0, r, goto fail);
6604418919fSjohnjiang 		}
661*2d9fd380Sjfb8856606 
662*2d9fd380Sjfb8856606 		/* Free memory before test completed */
663*2d9fd380Sjfb8856606 		rte_ring_free(r);
664*2d9fd380Sjfb8856606 		rte_free(src);
665*2d9fd380Sjfb8856606 		rte_free(dst);
666*2d9fd380Sjfb8856606 		r = NULL;
667*2d9fd380Sjfb8856606 		src = NULL;
668*2d9fd380Sjfb8856606 		dst = NULL;
669*2d9fd380Sjfb8856606 	}
670*2d9fd380Sjfb8856606 
6714418919fSjohnjiang 	return 0;
6724418919fSjohnjiang fail:
673*2d9fd380Sjfb8856606 	rte_ring_free(r);
674*2d9fd380Sjfb8856606 	rte_free(src);
675*2d9fd380Sjfb8856606 	rte_free(dst);
6764418919fSjohnjiang 	return -1;
6774418919fSjohnjiang }
6784418919fSjohnjiang 
679*2d9fd380Sjfb8856606 /*
680*2d9fd380Sjfb8856606  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
681*2d9fd380Sjfb8856606  * Sequence of simple enqueues/dequeues and validate the enqueued and
682*2d9fd380Sjfb8856606  * dequeued data.
683*2d9fd380Sjfb8856606  */
6844418919fSjohnjiang static int
test_ring_burst_bulk_tests2(unsigned int test_idx)685*2d9fd380Sjfb8856606 test_ring_burst_bulk_tests2(unsigned int test_idx)
6864418919fSjohnjiang {
687*2d9fd380Sjfb8856606 	struct rte_ring *r;
6884418919fSjohnjiang 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
6894418919fSjohnjiang 	int ret;
690*2d9fd380Sjfb8856606 	unsigned int i;
691*2d9fd380Sjfb8856606 
692*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
693*2d9fd380Sjfb8856606 		test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
694*2d9fd380Sjfb8856606 			test_enqdeq_impl[test_idx].api_type, esize[i]);
695*2d9fd380Sjfb8856606 
696*2d9fd380Sjfb8856606 		/* Create the ring */
697*2d9fd380Sjfb8856606 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
698*2d9fd380Sjfb8856606 				RING_SIZE, SOCKET_ID_ANY,
699*2d9fd380Sjfb8856606 				test_enqdeq_impl[test_idx].create_flags);
7004418919fSjohnjiang 
7014418919fSjohnjiang 		/* alloc dummy object pointers */
702*2d9fd380Sjfb8856606 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
7034418919fSjohnjiang 		if (src == NULL)
7044418919fSjohnjiang 			goto fail;
705*2d9fd380Sjfb8856606 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
7064418919fSjohnjiang 		cur_src = src;
7074418919fSjohnjiang 
7084418919fSjohnjiang 		/* alloc some room for copied objects */
709*2d9fd380Sjfb8856606 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
7104418919fSjohnjiang 		if (dst == NULL)
7114418919fSjohnjiang 			goto fail;
7124418919fSjohnjiang 		cur_dst = dst;
7134418919fSjohnjiang 
7144418919fSjohnjiang 		printf("enqueue 1 obj\n");
715*2d9fd380Sjfb8856606 		ret = test_ring_enq_impl(r, cur_src, esize[i], 1, test_idx);
716*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 1, r, goto fail);
717*2d9fd380Sjfb8856606 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
7184418919fSjohnjiang 
7194418919fSjohnjiang 		printf("enqueue 2 objs\n");
720*2d9fd380Sjfb8856606 		ret = test_ring_enq_impl(r, cur_src, esize[i], 2, test_idx);
721*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, r, goto fail);
722*2d9fd380Sjfb8856606 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
7234418919fSjohnjiang 
7244418919fSjohnjiang 		printf("enqueue MAX_BULK objs\n");
725*2d9fd380Sjfb8856606 		ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
726*2d9fd380Sjfb8856606 						test_idx);
727*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
7284418919fSjohnjiang 
7294418919fSjohnjiang 		printf("dequeue 1 obj\n");
730*2d9fd380Sjfb8856606 		ret = test_ring_deq_impl(r, cur_dst, esize[i], 1, test_idx);
731*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 1, r, goto fail);
732*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1);
7334418919fSjohnjiang 
7344418919fSjohnjiang 		printf("dequeue 2 objs\n");
735*2d9fd380Sjfb8856606 		ret = test_ring_deq_impl(r, cur_dst, esize[i], 2, test_idx);
736*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, r, goto fail);
737*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
7384418919fSjohnjiang 
7394418919fSjohnjiang 		printf("dequeue MAX_BULK objs\n");
740*2d9fd380Sjfb8856606 		ret = test_ring_deq_impl(r, cur_dst, esize[i], MAX_BULK,
741*2d9fd380Sjfb8856606 						test_idx);
742*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
743*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK);
7444418919fSjohnjiang 
7454418919fSjohnjiang 		/* check data */
746*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
747*2d9fd380Sjfb8856606 					RTE_PTR_DIFF(cur_dst, dst)) == 0,
748*2d9fd380Sjfb8856606 					r, goto fail);
749*2d9fd380Sjfb8856606 
750*2d9fd380Sjfb8856606 		/* Free memory before test completed */
751*2d9fd380Sjfb8856606 		rte_ring_free(r);
752*2d9fd380Sjfb8856606 		rte_free(src);
753*2d9fd380Sjfb8856606 		rte_free(dst);
754*2d9fd380Sjfb8856606 		r = NULL;
755*2d9fd380Sjfb8856606 		src = NULL;
756*2d9fd380Sjfb8856606 		dst = NULL;
7574418919fSjohnjiang 	}
7584418919fSjohnjiang 
759*2d9fd380Sjfb8856606 	return 0;
760*2d9fd380Sjfb8856606 fail:
761*2d9fd380Sjfb8856606 	rte_ring_free(r);
762*2d9fd380Sjfb8856606 	rte_free(src);
763*2d9fd380Sjfb8856606 	rte_free(dst);
764*2d9fd380Sjfb8856606 	return -1;
765*2d9fd380Sjfb8856606 }
766*2d9fd380Sjfb8856606 
767*2d9fd380Sjfb8856606 /*
768*2d9fd380Sjfb8856606  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
769*2d9fd380Sjfb8856606  * Enqueue and dequeue to cover the entire ring length.
770*2d9fd380Sjfb8856606  */
771*2d9fd380Sjfb8856606 static int
test_ring_burst_bulk_tests3(unsigned int test_idx)772*2d9fd380Sjfb8856606 test_ring_burst_bulk_tests3(unsigned int test_idx)
773*2d9fd380Sjfb8856606 {
774*2d9fd380Sjfb8856606 	struct rte_ring *r;
775*2d9fd380Sjfb8856606 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
776*2d9fd380Sjfb8856606 	int ret;
777*2d9fd380Sjfb8856606 	unsigned int i, j;
778*2d9fd380Sjfb8856606 
779*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
780*2d9fd380Sjfb8856606 		test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
781*2d9fd380Sjfb8856606 			test_enqdeq_impl[test_idx].api_type, esize[i]);
782*2d9fd380Sjfb8856606 
783*2d9fd380Sjfb8856606 		/* Create the ring */
784*2d9fd380Sjfb8856606 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
785*2d9fd380Sjfb8856606 				RING_SIZE, SOCKET_ID_ANY,
786*2d9fd380Sjfb8856606 				test_enqdeq_impl[test_idx].create_flags);
787*2d9fd380Sjfb8856606 
788*2d9fd380Sjfb8856606 		/* alloc dummy object pointers */
789*2d9fd380Sjfb8856606 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
790*2d9fd380Sjfb8856606 		if (src == NULL)
791*2d9fd380Sjfb8856606 			goto fail;
792*2d9fd380Sjfb8856606 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
7934418919fSjohnjiang 		cur_src = src;
794*2d9fd380Sjfb8856606 
795*2d9fd380Sjfb8856606 		/* alloc some room for copied objects */
796*2d9fd380Sjfb8856606 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
797*2d9fd380Sjfb8856606 		if (dst == NULL)
798*2d9fd380Sjfb8856606 			goto fail;
799*2d9fd380Sjfb8856606 		cur_dst = dst;
800*2d9fd380Sjfb8856606 
801*2d9fd380Sjfb8856606 		printf("fill and empty the ring\n");
802*2d9fd380Sjfb8856606 		for (j = 0; j < RING_SIZE / MAX_BULK; j++) {
803*2d9fd380Sjfb8856606 			ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
804*2d9fd380Sjfb8856606 							test_idx);
805*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
806*2d9fd380Sjfb8856606 			cur_src = test_ring_inc_ptr(cur_src, esize[i],
807*2d9fd380Sjfb8856606 								MAX_BULK);
808*2d9fd380Sjfb8856606 
809*2d9fd380Sjfb8856606 			ret = test_ring_deq_impl(r, cur_dst, esize[i], MAX_BULK,
810*2d9fd380Sjfb8856606 							test_idx);
811*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
812*2d9fd380Sjfb8856606 			cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
813*2d9fd380Sjfb8856606 								MAX_BULK);
814*2d9fd380Sjfb8856606 		}
815*2d9fd380Sjfb8856606 
816*2d9fd380Sjfb8856606 		/* check data */
817*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
818*2d9fd380Sjfb8856606 					RTE_PTR_DIFF(cur_dst, dst)) == 0,
819*2d9fd380Sjfb8856606 					r, goto fail);
820*2d9fd380Sjfb8856606 
821*2d9fd380Sjfb8856606 		/* Free memory before test completed */
822*2d9fd380Sjfb8856606 		rte_ring_free(r);
823*2d9fd380Sjfb8856606 		rte_free(src);
824*2d9fd380Sjfb8856606 		rte_free(dst);
825*2d9fd380Sjfb8856606 		r = NULL;
826*2d9fd380Sjfb8856606 		src = NULL;
827*2d9fd380Sjfb8856606 		dst = NULL;
828*2d9fd380Sjfb8856606 	}
829*2d9fd380Sjfb8856606 
830*2d9fd380Sjfb8856606 	return 0;
831*2d9fd380Sjfb8856606 fail:
832*2d9fd380Sjfb8856606 	rte_ring_free(r);
833*2d9fd380Sjfb8856606 	rte_free(src);
834*2d9fd380Sjfb8856606 	rte_free(dst);
835*2d9fd380Sjfb8856606 	return -1;
836*2d9fd380Sjfb8856606 }
837*2d9fd380Sjfb8856606 
838*2d9fd380Sjfb8856606 /*
839*2d9fd380Sjfb8856606  * Burst and bulk operations with sp/sc, mp/mc and default (during creation)
840*2d9fd380Sjfb8856606  * Enqueue till the ring is full and dequeue till the ring becomes empty.
841*2d9fd380Sjfb8856606  */
842*2d9fd380Sjfb8856606 static int
test_ring_burst_bulk_tests4(unsigned int test_idx)843*2d9fd380Sjfb8856606 test_ring_burst_bulk_tests4(unsigned int test_idx)
844*2d9fd380Sjfb8856606 {
845*2d9fd380Sjfb8856606 	struct rte_ring *r;
846*2d9fd380Sjfb8856606 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
847*2d9fd380Sjfb8856606 	int ret;
848*2d9fd380Sjfb8856606 	unsigned int i, j;
849*2d9fd380Sjfb8856606 	unsigned int api_type, num_elems;
850*2d9fd380Sjfb8856606 
851*2d9fd380Sjfb8856606 	api_type = test_enqdeq_impl[test_idx].api_type;
852*2d9fd380Sjfb8856606 
853*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
854*2d9fd380Sjfb8856606 		test_ring_print_test_string(test_enqdeq_impl[test_idx].desc,
855*2d9fd380Sjfb8856606 			test_enqdeq_impl[test_idx].api_type, esize[i]);
856*2d9fd380Sjfb8856606 
857*2d9fd380Sjfb8856606 		/* Create the ring */
858*2d9fd380Sjfb8856606 		r = test_ring_create("test_ring_burst_bulk_tests", esize[i],
859*2d9fd380Sjfb8856606 				RING_SIZE, SOCKET_ID_ANY,
860*2d9fd380Sjfb8856606 				test_enqdeq_impl[test_idx].create_flags);
861*2d9fd380Sjfb8856606 
862*2d9fd380Sjfb8856606 		/* alloc dummy object pointers */
863*2d9fd380Sjfb8856606 		src = test_ring_calloc(RING_SIZE * 2, esize[i]);
864*2d9fd380Sjfb8856606 		if (src == NULL)
865*2d9fd380Sjfb8856606 			goto fail;
866*2d9fd380Sjfb8856606 		test_ring_mem_init(src, RING_SIZE * 2, esize[i]);
867*2d9fd380Sjfb8856606 		cur_src = src;
868*2d9fd380Sjfb8856606 
869*2d9fd380Sjfb8856606 		/* alloc some room for copied objects */
870*2d9fd380Sjfb8856606 		dst = test_ring_calloc(RING_SIZE * 2, esize[i]);
871*2d9fd380Sjfb8856606 		if (dst == NULL)
872*2d9fd380Sjfb8856606 			goto fail;
8734418919fSjohnjiang 		cur_dst = dst;
8744418919fSjohnjiang 
8754418919fSjohnjiang 		printf("Test enqueue without enough memory space\n");
876*2d9fd380Sjfb8856606 		for (j = 0; j < (RING_SIZE/MAX_BULK - 1); j++) {
877*2d9fd380Sjfb8856606 			ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
878*2d9fd380Sjfb8856606 							test_idx);
879*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
880*2d9fd380Sjfb8856606 			cur_src = test_ring_inc_ptr(cur_src, esize[i],
881*2d9fd380Sjfb8856606 								MAX_BULK);
8824418919fSjohnjiang 		}
8834418919fSjohnjiang 
8844418919fSjohnjiang 		printf("Enqueue 2 objects, free entries = MAX_BULK - 2\n");
885*2d9fd380Sjfb8856606 		ret = test_ring_enq_impl(r, cur_src, esize[i], 2, test_idx);
886*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, r, goto fail);
887*2d9fd380Sjfb8856606 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
8884418919fSjohnjiang 
889*2d9fd380Sjfb8856606 		printf("Enqueue the remaining entries = MAX_BULK - 3\n");
890*2d9fd380Sjfb8856606 		/* Bulk APIs enqueue exact number of elements */
891*2d9fd380Sjfb8856606 		if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
892*2d9fd380Sjfb8856606 			num_elems = MAX_BULK - 3;
893*2d9fd380Sjfb8856606 		else
894*2d9fd380Sjfb8856606 			num_elems = MAX_BULK;
8954418919fSjohnjiang 		/* Always one free entry left */
896*2d9fd380Sjfb8856606 		ret = test_ring_enq_impl(r, cur_src, esize[i], num_elems,
897*2d9fd380Sjfb8856606 						test_idx);
898*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == MAX_BULK - 3, r, goto fail);
899*2d9fd380Sjfb8856606 		cur_src = test_ring_inc_ptr(cur_src, esize[i], MAX_BULK - 3);
9004418919fSjohnjiang 
9014418919fSjohnjiang 		printf("Test if ring is full\n");
902*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_full(r) == 1, r, goto fail);
9034418919fSjohnjiang 
9044418919fSjohnjiang 		printf("Test enqueue for a full entry\n");
905*2d9fd380Sjfb8856606 		ret = test_ring_enq_impl(r, cur_src, esize[i], MAX_BULK,
906*2d9fd380Sjfb8856606 						test_idx);
907*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 0, r, goto fail);
9084418919fSjohnjiang 
9094418919fSjohnjiang 		printf("Test dequeue without enough objects\n");
910*2d9fd380Sjfb8856606 		for (j = 0; j < RING_SIZE / MAX_BULK - 1; j++) {
911*2d9fd380Sjfb8856606 			ret = test_ring_deq_impl(r, cur_dst, esize[i], MAX_BULK,
912*2d9fd380Sjfb8856606 							test_idx);
913*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == MAX_BULK, r, goto fail);
914*2d9fd380Sjfb8856606 			cur_dst = test_ring_inc_ptr(cur_dst, esize[i],
915*2d9fd380Sjfb8856606 								MAX_BULK);
9164418919fSjohnjiang 		}
9174418919fSjohnjiang 
9184418919fSjohnjiang 		/* Available memory space for the exact MAX_BULK entries */
919*2d9fd380Sjfb8856606 		ret = test_ring_deq_impl(r, cur_dst, esize[i], 2, test_idx);
920*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, r, goto fail);
921*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
9224418919fSjohnjiang 
923*2d9fd380Sjfb8856606 		/* Bulk APIs enqueue exact number of elements */
924*2d9fd380Sjfb8856606 		if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
925*2d9fd380Sjfb8856606 			num_elems = MAX_BULK - 3;
926*2d9fd380Sjfb8856606 		else
927*2d9fd380Sjfb8856606 			num_elems = MAX_BULK;
928*2d9fd380Sjfb8856606 		ret = test_ring_deq_impl(r, cur_dst, esize[i], num_elems,
929*2d9fd380Sjfb8856606 						test_idx);
930*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == MAX_BULK - 3, r, goto fail);
931*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], MAX_BULK - 3);
9324418919fSjohnjiang 
9334418919fSjohnjiang 		printf("Test if ring is empty\n");
9344418919fSjohnjiang 		/* Check if ring is empty */
935*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_empty(r) == 1, r, goto fail);
9364418919fSjohnjiang 
9374418919fSjohnjiang 		/* check data */
938*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
939*2d9fd380Sjfb8856606 					RTE_PTR_DIFF(cur_dst, dst)) == 0,
940*2d9fd380Sjfb8856606 					r, goto fail);
9414418919fSjohnjiang 
9424418919fSjohnjiang 		/* Free memory before test completed */
943*2d9fd380Sjfb8856606 		rte_ring_free(r);
944*2d9fd380Sjfb8856606 		rte_free(src);
945*2d9fd380Sjfb8856606 		rte_free(dst);
946*2d9fd380Sjfb8856606 		r = NULL;
947*2d9fd380Sjfb8856606 		src = NULL;
948*2d9fd380Sjfb8856606 		dst = NULL;
949*2d9fd380Sjfb8856606 	}
9504418919fSjohnjiang 
951*2d9fd380Sjfb8856606 	return 0;
9524418919fSjohnjiang fail:
953*2d9fd380Sjfb8856606 	rte_ring_free(r);
954*2d9fd380Sjfb8856606 	rte_free(src);
955*2d9fd380Sjfb8856606 	rte_free(dst);
9564418919fSjohnjiang 	return -1;
9574418919fSjohnjiang }
9584418919fSjohnjiang 
9594418919fSjohnjiang /*
960*2d9fd380Sjfb8856606  * Test default, single element, bulk and burst APIs
9614418919fSjohnjiang  */
9624418919fSjohnjiang static int
test_ring_basic_ex(void)9634418919fSjohnjiang test_ring_basic_ex(void)
9644418919fSjohnjiang {
9654418919fSjohnjiang 	int ret = -1;
966*2d9fd380Sjfb8856606 	unsigned int i, j;
9674418919fSjohnjiang 	struct rte_ring *rp = NULL;
968*2d9fd380Sjfb8856606 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
9694418919fSjohnjiang 
970*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
971*2d9fd380Sjfb8856606 		rp = test_ring_create("test_ring_basic_ex", esize[i], RING_SIZE,
972*2d9fd380Sjfb8856606 					SOCKET_ID_ANY,
9734418919fSjohnjiang 					RING_F_SP_ENQ | RING_F_SC_DEQ);
9744418919fSjohnjiang 		if (rp == NULL) {
975*2d9fd380Sjfb8856606 			printf("%s: failed to create ring\n", __func__);
9764418919fSjohnjiang 			goto fail_test;
9774418919fSjohnjiang 		}
9784418919fSjohnjiang 
979*2d9fd380Sjfb8856606 		/* alloc dummy object pointers */
980*2d9fd380Sjfb8856606 		src = test_ring_calloc(RING_SIZE, esize[i]);
981*2d9fd380Sjfb8856606 		if (src == NULL) {
982*2d9fd380Sjfb8856606 			printf("%s: failed to alloc src memory\n", __func__);
9834418919fSjohnjiang 			goto fail_test;
9844418919fSjohnjiang 		}
985*2d9fd380Sjfb8856606 		test_ring_mem_init(src, RING_SIZE, esize[i]);
986*2d9fd380Sjfb8856606 		cur_src = src;
9874418919fSjohnjiang 
988*2d9fd380Sjfb8856606 		/* alloc some room for copied objects */
989*2d9fd380Sjfb8856606 		dst = test_ring_calloc(RING_SIZE, esize[i]);
990*2d9fd380Sjfb8856606 		if (dst == NULL) {
991*2d9fd380Sjfb8856606 			printf("%s: failed to alloc dst memory\n", __func__);
9924418919fSjohnjiang 			goto fail_test;
9934418919fSjohnjiang 		}
994*2d9fd380Sjfb8856606 		cur_dst = dst;
9954418919fSjohnjiang 
996*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_lookup("test_ring_basic_ex") == rp,
997*2d9fd380Sjfb8856606 					rp, goto fail_test);
9984418919fSjohnjiang 
999*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_empty(rp) == 1, rp, goto fail_test);
1000*2d9fd380Sjfb8856606 
1001*2d9fd380Sjfb8856606 		printf("%u ring entries are now free\n",
1002*2d9fd380Sjfb8856606 			rte_ring_free_count(rp));
1003*2d9fd380Sjfb8856606 
1004*2d9fd380Sjfb8856606 		for (j = 0; j < RING_SIZE - 1; j++) {
1005*2d9fd380Sjfb8856606 			ret = test_ring_enqueue(rp, cur_src, esize[i], 1,
1006*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1007*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == 0, rp, goto fail_test);
1008*2d9fd380Sjfb8856606 			cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
10094418919fSjohnjiang 		}
10104418919fSjohnjiang 
1011*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_full(rp) == 1, rp, goto fail_test);
1012*2d9fd380Sjfb8856606 
1013*2d9fd380Sjfb8856606 		for (j = 0; j < RING_SIZE - 1; j++) {
1014*2d9fd380Sjfb8856606 			ret = test_ring_dequeue(rp, cur_dst, esize[i], 1,
1015*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1016*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == 0, rp, goto fail_test);
1017*2d9fd380Sjfb8856606 			cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 1);
10184418919fSjohnjiang 		}
10194418919fSjohnjiang 
1020*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_empty(rp) == 1, rp, goto fail_test);
10214418919fSjohnjiang 
1022*2d9fd380Sjfb8856606 		/* check data */
1023*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
1024*2d9fd380Sjfb8856606 					RTE_PTR_DIFF(cur_dst, dst)) == 0,
1025*2d9fd380Sjfb8856606 					rp, goto fail_test);
1026*2d9fd380Sjfb8856606 
1027*2d9fd380Sjfb8856606 		/* Following tests use the configured flags to decide
1028*2d9fd380Sjfb8856606 		 * SP/SC or MP/MC.
1029*2d9fd380Sjfb8856606 		 */
1030*2d9fd380Sjfb8856606 		/* reset memory of dst */
1031*2d9fd380Sjfb8856606 		memset(dst, 0, RTE_PTR_DIFF(cur_dst, dst));
1032*2d9fd380Sjfb8856606 
1033*2d9fd380Sjfb8856606 		/* reset cur_src and cur_dst */
1034*2d9fd380Sjfb8856606 		cur_src = src;
1035*2d9fd380Sjfb8856606 		cur_dst = dst;
10364418919fSjohnjiang 
10374418919fSjohnjiang 		/* Covering the ring burst operation */
1038*2d9fd380Sjfb8856606 		ret = test_ring_enqueue(rp, cur_src, esize[i], 2,
1039*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
1040*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1041*2d9fd380Sjfb8856606 		cur_src = test_ring_inc_ptr(cur_src, esize[i], 2);
1042*2d9fd380Sjfb8856606 
1043*2d9fd380Sjfb8856606 		ret = test_ring_dequeue(rp, cur_dst, esize[i], 2,
1044*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
1045*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1046*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
1047*2d9fd380Sjfb8856606 
1048*2d9fd380Sjfb8856606 		/* Covering the ring bulk operation */
1049*2d9fd380Sjfb8856606 		ret = test_ring_enqueue(rp, cur_src, esize[i], 2,
1050*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
1051*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1052*2d9fd380Sjfb8856606 
1053*2d9fd380Sjfb8856606 		ret = test_ring_dequeue(rp, cur_dst, esize[i], 2,
1054*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BULK);
1055*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == 2, rp, goto fail_test);
1056*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], 2);
1057*2d9fd380Sjfb8856606 
1058*2d9fd380Sjfb8856606 		/* check data */
1059*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
1060*2d9fd380Sjfb8856606 					RTE_PTR_DIFF(cur_dst, dst)) == 0,
1061*2d9fd380Sjfb8856606 					rp, goto fail_test);
1062*2d9fd380Sjfb8856606 
1063*2d9fd380Sjfb8856606 		rte_ring_free(rp);
1064*2d9fd380Sjfb8856606 		rte_free(src);
1065*2d9fd380Sjfb8856606 		rte_free(dst);
1066*2d9fd380Sjfb8856606 		rp = NULL;
1067*2d9fd380Sjfb8856606 		src = NULL;
1068*2d9fd380Sjfb8856606 		dst = NULL;
10694418919fSjohnjiang 	}
10704418919fSjohnjiang 
1071*2d9fd380Sjfb8856606 	return 0;
10724418919fSjohnjiang 
10734418919fSjohnjiang fail_test:
10744418919fSjohnjiang 	rte_ring_free(rp);
1075*2d9fd380Sjfb8856606 	rte_free(src);
1076*2d9fd380Sjfb8856606 	rte_free(dst);
1077*2d9fd380Sjfb8856606 	return -1;
10784418919fSjohnjiang }
10794418919fSjohnjiang 
1080*2d9fd380Sjfb8856606 /*
1081*2d9fd380Sjfb8856606  * Basic test cases with exact size ring.
1082*2d9fd380Sjfb8856606  */
10834418919fSjohnjiang static int
test_ring_with_exact_size(void)10844418919fSjohnjiang test_ring_with_exact_size(void)
10854418919fSjohnjiang {
1086*2d9fd380Sjfb8856606 	struct rte_ring *std_r = NULL, *exact_sz_r = NULL;
1087*2d9fd380Sjfb8856606 	void **src_orig = NULL, **dst_orig = NULL;
1088*2d9fd380Sjfb8856606 	void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
1089*2d9fd380Sjfb8856606 	const unsigned int ring_sz = 16;
1090*2d9fd380Sjfb8856606 	unsigned int i, j;
10914418919fSjohnjiang 	int ret = -1;
10924418919fSjohnjiang 
1093*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(esize); i++) {
1094*2d9fd380Sjfb8856606 		test_ring_print_test_string("Test exact size ring",
1095*2d9fd380Sjfb8856606 				TEST_RING_IGNORE_API_TYPE,
1096*2d9fd380Sjfb8856606 				esize[i]);
1097*2d9fd380Sjfb8856606 
1098*2d9fd380Sjfb8856606 		std_r = test_ring_create("std", esize[i], ring_sz,
1099*2d9fd380Sjfb8856606 					rte_socket_id(),
11004418919fSjohnjiang 					RING_F_SP_ENQ | RING_F_SC_DEQ);
1101*2d9fd380Sjfb8856606 		if (std_r == NULL) {
11024418919fSjohnjiang 			printf("%s: error, can't create std ring\n", __func__);
1103*2d9fd380Sjfb8856606 			goto test_fail;
11044418919fSjohnjiang 		}
1105*2d9fd380Sjfb8856606 		exact_sz_r = test_ring_create("exact sz", esize[i], ring_sz,
1106*2d9fd380Sjfb8856606 				rte_socket_id(),
1107*2d9fd380Sjfb8856606 				RING_F_SP_ENQ | RING_F_SC_DEQ |
1108*2d9fd380Sjfb8856606 				RING_F_EXACT_SZ);
1109*2d9fd380Sjfb8856606 		if (exact_sz_r == NULL) {
1110*2d9fd380Sjfb8856606 			printf("%s: error, can't create exact size ring\n",
1111*2d9fd380Sjfb8856606 					__func__);
1112*2d9fd380Sjfb8856606 			goto test_fail;
11134418919fSjohnjiang 		}
11144418919fSjohnjiang 
1115*2d9fd380Sjfb8856606 		/* alloc object pointers. Allocate one extra object
1116*2d9fd380Sjfb8856606 		 * and create an unaligned address.
11174418919fSjohnjiang 		 */
1118*2d9fd380Sjfb8856606 		src_orig = test_ring_calloc(17, esize[i]);
1119*2d9fd380Sjfb8856606 		if (src_orig == NULL)
1120*2d9fd380Sjfb8856606 			goto test_fail;
1121*2d9fd380Sjfb8856606 		test_ring_mem_init(src_orig, 17, esize[i]);
1122*2d9fd380Sjfb8856606 		src = (void **)((uintptr_t)src_orig + 1);
1123*2d9fd380Sjfb8856606 		cur_src = src;
1124*2d9fd380Sjfb8856606 
1125*2d9fd380Sjfb8856606 		dst_orig = test_ring_calloc(17, esize[i]);
1126*2d9fd380Sjfb8856606 		if (dst_orig == NULL)
1127*2d9fd380Sjfb8856606 			goto test_fail;
1128*2d9fd380Sjfb8856606 		dst = (void **)((uintptr_t)dst_orig + 1);
1129*2d9fd380Sjfb8856606 		cur_dst = dst;
1130*2d9fd380Sjfb8856606 
11314418919fSjohnjiang 		/*
1132*2d9fd380Sjfb8856606 		 * Check that the exact size ring is bigger than the
1133*2d9fd380Sjfb8856606 		 * standard ring
11344418919fSjohnjiang 		 */
1135*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_get_size(std_r) <=
1136*2d9fd380Sjfb8856606 				rte_ring_get_size(exact_sz_r),
1137*2d9fd380Sjfb8856606 				std_r, goto test_fail);
1138*2d9fd380Sjfb8856606 
1139*2d9fd380Sjfb8856606 		/*
1140*2d9fd380Sjfb8856606 		 * check that the exact_sz_ring can hold one more element
1141*2d9fd380Sjfb8856606 		 * than the standard ring. (16 vs 15 elements)
1142*2d9fd380Sjfb8856606 		 */
1143*2d9fd380Sjfb8856606 		for (j = 0; j < ring_sz - 1; j++) {
1144*2d9fd380Sjfb8856606 			ret = test_ring_enqueue(std_r, cur_src, esize[i], 1,
1145*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1146*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == 0, std_r, goto test_fail);
1147*2d9fd380Sjfb8856606 			ret = test_ring_enqueue(exact_sz_r, cur_src, esize[i], 1,
1148*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1149*2d9fd380Sjfb8856606 			TEST_RING_VERIFY(ret == 0, exact_sz_r, goto test_fail);
1150*2d9fd380Sjfb8856606 			cur_src = test_ring_inc_ptr(cur_src, esize[i], 1);
11514418919fSjohnjiang 		}
1152*2d9fd380Sjfb8856606 		ret = test_ring_enqueue(std_r, cur_src, esize[i], 1,
1153*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1154*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == -ENOBUFS, std_r, goto test_fail);
1155*2d9fd380Sjfb8856606 		ret = test_ring_enqueue(exact_sz_r, cur_src, esize[i], 1,
1156*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_SINGLE);
1157*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret != -ENOBUFS, exact_sz_r, goto test_fail);
11584418919fSjohnjiang 
11594418919fSjohnjiang 		/* check that dequeue returns the expected number of elements */
1160*2d9fd380Sjfb8856606 		ret = test_ring_dequeue(exact_sz_r, cur_dst, esize[i], ring_sz,
1161*2d9fd380Sjfb8856606 				TEST_RING_THREAD_DEF | TEST_RING_ELEM_BURST);
1162*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(ret == (int)ring_sz, exact_sz_r, goto test_fail);
1163*2d9fd380Sjfb8856606 		cur_dst = test_ring_inc_ptr(cur_dst, esize[i], ring_sz);
11644418919fSjohnjiang 
11654418919fSjohnjiang 		/* check that the capacity function returns expected value */
1166*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(rte_ring_get_capacity(exact_sz_r) == ring_sz,
1167*2d9fd380Sjfb8856606 					exact_sz_r, goto test_fail);
1168*2d9fd380Sjfb8856606 
1169*2d9fd380Sjfb8856606 		/* check data */
1170*2d9fd380Sjfb8856606 		TEST_RING_VERIFY(test_ring_mem_cmp(src, dst,
1171*2d9fd380Sjfb8856606 					RTE_PTR_DIFF(cur_dst, dst)) == 0,
1172*2d9fd380Sjfb8856606 					exact_sz_r, goto test_fail);
1173*2d9fd380Sjfb8856606 
1174*2d9fd380Sjfb8856606 		rte_free(src_orig);
1175*2d9fd380Sjfb8856606 		rte_free(dst_orig);
1176*2d9fd380Sjfb8856606 		rte_ring_free(std_r);
1177*2d9fd380Sjfb8856606 		rte_ring_free(exact_sz_r);
1178*2d9fd380Sjfb8856606 		src_orig = NULL;
1179*2d9fd380Sjfb8856606 		dst_orig = NULL;
1180*2d9fd380Sjfb8856606 		std_r = NULL;
1181*2d9fd380Sjfb8856606 		exact_sz_r = NULL;
11824418919fSjohnjiang 	}
11834418919fSjohnjiang 
1184*2d9fd380Sjfb8856606 	return 0;
1185*2d9fd380Sjfb8856606 
1186*2d9fd380Sjfb8856606 test_fail:
1187*2d9fd380Sjfb8856606 	rte_free(src_orig);
1188*2d9fd380Sjfb8856606 	rte_free(dst_orig);
1189*2d9fd380Sjfb8856606 	rte_ring_free(std_r);
1190*2d9fd380Sjfb8856606 	rte_ring_free(exact_sz_r);
1191*2d9fd380Sjfb8856606 	return -1;
11924418919fSjohnjiang }
11934418919fSjohnjiang 
11944418919fSjohnjiang static int
test_ring(void)11954418919fSjohnjiang test_ring(void)
11964418919fSjohnjiang {
1197*2d9fd380Sjfb8856606 	int32_t rc;
1198*2d9fd380Sjfb8856606 	unsigned int i;
11994418919fSjohnjiang 
1200*2d9fd380Sjfb8856606 	/* Negative test cases */
1201*2d9fd380Sjfb8856606 	if (test_ring_negative_tests() < 0)
1202*2d9fd380Sjfb8856606 		goto test_fail;
1203*2d9fd380Sjfb8856606 
1204*2d9fd380Sjfb8856606 	/* Some basic operations */
12054418919fSjohnjiang 	if (test_ring_basic_ex() < 0)
12064418919fSjohnjiang 		goto test_fail;
12074418919fSjohnjiang 
12084418919fSjohnjiang 	if (test_ring_with_exact_size() < 0)
12094418919fSjohnjiang 		goto test_fail;
12104418919fSjohnjiang 
1211*2d9fd380Sjfb8856606 	/* Burst and bulk operations with sp/sc, mp/mc and default.
1212*2d9fd380Sjfb8856606 	 * The test cases are split into smaller test cases to
1213*2d9fd380Sjfb8856606 	 * help clang compile faster.
1214*2d9fd380Sjfb8856606 	 */
1215*2d9fd380Sjfb8856606 	for (i = 0; i != RTE_DIM(test_enqdeq_impl); i++) {
1216*2d9fd380Sjfb8856606 
1217*2d9fd380Sjfb8856606 
1218*2d9fd380Sjfb8856606 		rc = test_ring_burst_bulk_tests1(i);
1219*2d9fd380Sjfb8856606 		if (rc < 0)
1220*2d9fd380Sjfb8856606 			goto test_fail;
1221*2d9fd380Sjfb8856606 
1222*2d9fd380Sjfb8856606 		rc = test_ring_burst_bulk_tests2(i);
1223*2d9fd380Sjfb8856606 		if (rc < 0)
1224*2d9fd380Sjfb8856606 			goto test_fail;
1225*2d9fd380Sjfb8856606 
1226*2d9fd380Sjfb8856606 		rc = test_ring_burst_bulk_tests3(i);
1227*2d9fd380Sjfb8856606 		if (rc < 0)
1228*2d9fd380Sjfb8856606 			goto test_fail;
1229*2d9fd380Sjfb8856606 
1230*2d9fd380Sjfb8856606 		rc = test_ring_burst_bulk_tests4(i);
1231*2d9fd380Sjfb8856606 		if (rc < 0)
1232*2d9fd380Sjfb8856606 			goto test_fail;
1233*2d9fd380Sjfb8856606 	}
1234*2d9fd380Sjfb8856606 
12354418919fSjohnjiang 	/* dump the ring status */
12364418919fSjohnjiang 	rte_ring_list_dump(stdout);
12374418919fSjohnjiang 
12384418919fSjohnjiang 	return 0;
12394418919fSjohnjiang 
12404418919fSjohnjiang test_fail:
12414418919fSjohnjiang 
12424418919fSjohnjiang 	return -1;
12434418919fSjohnjiang }
12444418919fSjohnjiang 
12454418919fSjohnjiang REGISTER_TEST_COMMAND(ring_autotest, test_ring);
1246