xref: /dpdk/app/test/test_pmd_ring.c (revision 14ad4f01845331a0ae98c681efa3086eeed3343a)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2015 Intel Corporation
3  */
4 #include "test.h"
5 #include <string.h>
6 
7 #include <stdio.h>
8 
9 #include <rte_eth_ring.h>
10 #include <rte_ethdev.h>
11 #include <rte_bus_vdev.h>
12 
13 #define SOCKET0 0
14 #define RING_SIZE 256
15 #define NUM_RINGS 2
16 #define NB_MBUF 512
17 
18 static struct rte_mempool *mp;
19 struct rte_ring *rxtx[NUM_RINGS];
20 static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte;
21 
22 static int
23 test_ethdev_configure_port(int port)
24 {
25 	struct rte_eth_conf null_conf;
26 	struct rte_eth_link link;
27 
28 	memset(&null_conf, 0, sizeof(struct rte_eth_conf));
29 
30 	if (rte_eth_dev_configure(port, 1, 2, &null_conf) < 0) {
31 		printf("Configure failed for port %d\n", port);
32 		return -1;
33 	}
34 
35 	/* Test queue release */
36 	if (rte_eth_dev_configure(port, 1, 1, &null_conf) < 0) {
37 		printf("Configure failed for port %d\n", port);
38 		return -1;
39 	}
40 
41 	if (rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL) < 0) {
42 		printf("TX queue setup failed port %d\n", port);
43 		return -1;
44 	}
45 
46 	if (rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0,
47 				NULL, mp) < 0) {
48 		printf("RX queue setup failed port %d\n", port);
49 		return -1;
50 	}
51 
52 	if (rte_eth_dev_start(port) < 0) {
53 		printf("Error starting port %d\n", port);
54 		return -1;
55 	}
56 
57 	rte_eth_link_get(port, &link);
58 
59 	return 0;
60 }
61 
62 static int
63 test_send_basic_packets(void)
64 {
65 	struct rte_mbuf  bufs[RING_SIZE];
66 	struct rte_mbuf *pbufs[RING_SIZE];
67 	int i;
68 
69 	printf("Testing send and receive RING_SIZE/2 packets (tx_porta -> rx_portb)\n");
70 
71 	for (i = 0; i < RING_SIZE/2; i++)
72 		pbufs[i] = &bufs[i];
73 
74 	if (rte_eth_tx_burst(tx_porta, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) {
75 		printf("Failed to transmit packet burst port %d\n", tx_porta);
76 		return TEST_FAILED;
77 	}
78 
79 	if (rte_eth_rx_burst(rx_portb, 0, pbufs, RING_SIZE) != RING_SIZE/2) {
80 		printf("Failed to receive packet burst on port %d\n", rx_portb);
81 		return TEST_FAILED;
82 	}
83 
84 	for (i = 0; i < RING_SIZE/2; i++)
85 		if (pbufs[i] != &bufs[i]) {
86 			printf("Error: received data does not match that transmitted\n");
87 			return TEST_FAILED;
88 		}
89 
90 	return TEST_SUCCESS;
91 }
92 
93 static int
94 test_send_basic_packets_port(int port)
95 {
96 	struct rte_mbuf  bufs[RING_SIZE];
97 	struct rte_mbuf *pbufs[RING_SIZE];
98 	int i;
99 
100 	printf("Testing send and receive RING_SIZE/2 packets (cmdl_port0 -> cmdl_port0)\n");
101 
102 	for (i = 0; i < RING_SIZE/2; i++)
103 		pbufs[i] = &bufs[i];
104 
105 	if (rte_eth_tx_burst(port, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) {
106 		printf("Failed to transmit packet burst port %d\n", port);
107 		return -1;
108 	}
109 
110 	if (rte_eth_rx_burst(port, 0, pbufs, RING_SIZE) != RING_SIZE/2) {
111 		printf("Failed to receive packet burst on port %d\n", port);
112 		return -1;
113 	}
114 
115 	for (i = 0; i < RING_SIZE/2; i++)
116 		if (pbufs[i] != &bufs[i]) {
117 			printf("Error: received data does not match that transmitted\n");
118 			return -1;
119 		}
120 
121 	return 0;
122 }
123 
124 
125 static int
126 test_get_stats(int port)
127 {
128 	struct rte_eth_stats stats;
129 	struct rte_mbuf buf, *pbuf = &buf;
130 
131 	printf("Testing ring PMD stats_get port %d\n", port);
132 
133 	/* check stats of RXTX port, should all be zero */
134 
135 	rte_eth_stats_get(port, &stats);
136 	if (stats.ipackets != 0 || stats.opackets != 0 ||
137 			stats.ibytes != 0 || stats.obytes != 0 ||
138 			stats.ierrors != 0 || stats.oerrors != 0) {
139 		printf("Error: port %d stats are not zero\n", port);
140 		return -1;
141 	}
142 
143 	/* send and receive 1 packet and check for stats update */
144 	if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) {
145 		printf("Error sending packet to port %d\n", port);
146 		return -1;
147 	}
148 
149 	if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) {
150 		printf("Error receiving packet from port %d\n", port);
151 		return -1;
152 	}
153 
154 	rte_eth_stats_get(port, &stats);
155 	if (stats.ipackets != 1 || stats.opackets != 1 ||
156 			stats.ibytes != 0 || stats.obytes != 0 ||
157 			stats.ierrors != 0 || stats.oerrors != 0) {
158 		printf("Error: port %d stats are not as expected\n", port);
159 		return -1;
160 	}
161 	return 0;
162 }
163 
164 static int
165 test_stats_reset(int port)
166 {
167 	struct rte_eth_stats stats;
168 	struct rte_mbuf buf, *pbuf = &buf;
169 
170 	printf("Testing ring PMD stats_reset port %d\n", port);
171 
172 	rte_eth_stats_reset(port);
173 
174 	/* check stats of RXTX port, should all be zero */
175 	rte_eth_stats_get(port, &stats);
176 	if (stats.ipackets != 0 || stats.opackets != 0 ||
177 			stats.ibytes != 0 || stats.obytes != 0 ||
178 			stats.ierrors != 0 || stats.oerrors != 0) {
179 		printf("Error: port %d stats are not zero\n", port);
180 		return -1;
181 	}
182 
183 	/* send and receive 1 packet and check for stats update */
184 	if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) {
185 		printf("Error sending packet to port %d\n", port);
186 		return -1;
187 	}
188 
189 	if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) {
190 		printf("Error receiving packet from port %d\n", port);
191 		return -1;
192 	}
193 
194 	rte_eth_stats_get(port, &stats);
195 	if (stats.ipackets != 1 || stats.opackets != 1 ||
196 			stats.ibytes != 0 || stats.obytes != 0 ||
197 			stats.ierrors != 0 || stats.oerrors != 0) {
198 		printf("Error: port %d stats are not as expected\n", port);
199 		return -1;
200 	}
201 
202 	rte_eth_stats_reset(port);
203 
204 	/* check stats of RXTX port, should all be zero */
205 	rte_eth_stats_get(port, &stats);
206 	if (stats.ipackets != 0 || stats.opackets != 0 ||
207 			stats.ibytes != 0 || stats.obytes != 0 ||
208 			stats.ierrors != 0 || stats.oerrors != 0) {
209 		printf("Error: port %d stats are not zero\n", port);
210 		return -1;
211 	}
212 
213 	return 0;
214 }
215 
216 static int
217 test_pmd_ring_pair_create_attach(void)
218 {
219 	struct rte_eth_stats stats, stats2;
220 	struct rte_mbuf buf, *pbuf = &buf;
221 	struct rte_eth_conf null_conf;
222 
223 	memset(&null_conf, 0, sizeof(struct rte_eth_conf));
224 
225 	if ((rte_eth_dev_configure(rxtx_portd, 1, 1, &null_conf) < 0)
226 			|| (rte_eth_dev_configure(rxtx_porte, 1, 1,
227 					&null_conf) < 0)) {
228 		printf("Configure failed for port\n");
229 		return TEST_FAILED;
230 	}
231 
232 	if ((rte_eth_tx_queue_setup(rxtx_portd, 0, RING_SIZE,
233 					SOCKET0, NULL) < 0)
234 			|| (rte_eth_tx_queue_setup(rxtx_porte, 0, RING_SIZE,
235 					SOCKET0, NULL) < 0)) {
236 		printf("TX queue setup failed\n");
237 		return TEST_FAILED;
238 	}
239 
240 	if ((rte_eth_rx_queue_setup(rxtx_portd, 0, RING_SIZE,
241 					SOCKET0, NULL, mp) < 0)
242 			|| (rte_eth_rx_queue_setup(rxtx_porte, 0, RING_SIZE,
243 					SOCKET0, NULL, mp) < 0)) {
244 		printf("RX queue setup failed\n");
245 		return TEST_FAILED;
246 	}
247 
248 	if ((rte_eth_dev_start(rxtx_portd) < 0)
249 			|| (rte_eth_dev_start(rxtx_porte) < 0)) {
250 		printf("Error starting port\n");
251 		return TEST_FAILED;
252 	}
253 
254 	rte_eth_stats_reset(rxtx_portd);
255 	/* check stats of port, should all be zero */
256 	rte_eth_stats_get(rxtx_portd, &stats);
257 	if (stats.ipackets != 0 || stats.opackets != 0 ||
258 			stats.ibytes != 0 || stats.obytes != 0 ||
259 			stats.ierrors != 0 || stats.oerrors != 0) {
260 		printf("Error: port %d stats are not zero\n", rxtx_portd);
261 		return TEST_FAILED;
262 	}
263 
264 	rte_eth_stats_reset(rxtx_porte);
265 	/* check stats of port, should all be zero */
266 	rte_eth_stats_get(rxtx_porte, &stats2);
267 	if (stats2.ipackets != 0 || stats2.opackets != 0 ||
268 			stats2.ibytes != 0 || stats2.obytes != 0 ||
269 			stats2.ierrors != 0 || stats2.oerrors != 0) {
270 		printf("Error: port %d stats are not zero\n", rxtx_porte);
271 		return TEST_FAILED;
272 	}
273 
274 	/*
275 	 * send and receive 1 packet (rxtx_portd -> rxtx_porte)
276 	 * and check for stats update
277 	 */
278 	printf("Testing send and receive 1 packet (rxtx_portd -> rxtx_porte)\n");
279 	if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) {
280 		printf("Error sending packet to port %d\n", rxtx_portd);
281 		return TEST_FAILED;
282 	}
283 
284 	if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) {
285 		printf("Error receiving packet from port %d\n", rxtx_porte);
286 		return TEST_FAILED;
287 	}
288 
289 	rte_eth_stats_get(rxtx_portd, &stats);
290 	rte_eth_stats_get(rxtx_porte, &stats2);
291 	if (stats.ipackets != 0 || stats.opackets != 1 ||
292 			stats.ibytes != 0 || stats.obytes != 0 ||
293 			stats.ierrors != 0 || stats.oerrors != 0) {
294 		printf("Error: port %d stats are not as expected\n",
295 				rxtx_portd);
296 		return TEST_FAILED;
297 	}
298 
299 	if (stats2.ipackets != 1 || stats2.opackets != 0 ||
300 			stats2.ibytes != 0 || stats2.obytes != 0 ||
301 			stats2.ierrors != 0 || stats2.oerrors != 0) {
302 		printf("Error: port %d stats are not as expected\n",
303 				rxtx_porte);
304 		return TEST_FAILED;
305 	}
306 
307 	/*
308 	 * send and receive 1 packet (rxtx_porte -> rxtx_portd)
309 	 * and check for stats update
310 	 */
311 	printf("Testing send and receive 1 packet "
312 			"(rxtx_porte -> rxtx_portd)\n");
313 	if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) {
314 		printf("Error sending packet to port %d\n", rxtx_porte);
315 		return TEST_FAILED;
316 	}
317 
318 	if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) {
319 		printf("Error receiving packet from port %d\n", rxtx_portd);
320 		return TEST_FAILED;
321 	}
322 
323 	rte_eth_stats_get(rxtx_portd, &stats);
324 	rte_eth_stats_get(rxtx_porte, &stats2);
325 	if (stats.ipackets != 1 || stats.opackets != 1 ||
326 			stats.ibytes != 0 || stats.obytes != 0 ||
327 			stats.ierrors != 0 || stats.oerrors != 0) {
328 		printf("Error: port %d stats are not as expected\n",
329 				rxtx_portd);
330 		return TEST_FAILED;
331 	}
332 
333 	if (stats2.ipackets != 1 || stats2.opackets != 1 ||
334 			stats2.ibytes != 0 || stats2.obytes != 0 ||
335 			stats2.ierrors != 0 || stats2.oerrors != 0) {
336 		printf("Error: port %d stats are not as expected\n",
337 				rxtx_porte);
338 		return TEST_FAILED;
339 	}
340 
341 	/*
342 	 * send and receive 1 packet (rxtx_portd -> rxtx_portd)
343 	 * and check for stats update
344 	 */
345 	printf("Testing send and receive 1 packet "
346 			"(rxtx_portd -> rxtx_portd)\n");
347 	if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) {
348 		printf("Error sending packet to port %d\n", rxtx_portd);
349 		return TEST_FAILED;
350 	}
351 
352 	if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) {
353 		printf("Error receiving packet from port %d\n", rxtx_porte);
354 		return TEST_FAILED;
355 	}
356 
357 	rte_eth_stats_get(rxtx_portd, &stats);
358 	rte_eth_stats_get(rxtx_porte, &stats2);
359 	if (stats.ipackets != 2 || stats.opackets != 2 ||
360 			stats.ibytes != 0 || stats.obytes != 0 ||
361 			stats.ierrors != 0 || stats.oerrors != 0) {
362 		printf("Error: port %d stats are not as expected\n",
363 				rxtx_portd);
364 		return TEST_FAILED;
365 	}
366 
367 	if (stats2.ipackets != 1 || stats2.opackets != 1 ||
368 			stats2.ibytes != 0 || stats2.obytes != 0 ||
369 			stats2.ierrors != 0 || stats2.oerrors != 0) {
370 		printf("Error: port %d stats are not as expected\n",
371 				rxtx_porte);
372 		return TEST_FAILED;
373 	}
374 
375 	/*
376 	 * send and receive 1 packet (rxtx_porte -> rxtx_porte)
377 	 * and check for stats update
378 	 */
379 	printf("Testing send and receive 1 packet "
380 			"(rxtx_porte -> rxtx_porte)\n");
381 	if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) {
382 		printf("Error sending packet to port %d\n", rxtx_porte);
383 		return TEST_FAILED;
384 	}
385 
386 	if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) {
387 		printf("Error receiving packet from port %d\n", rxtx_porte);
388 		return TEST_FAILED;
389 	}
390 
391 	rte_eth_stats_get(rxtx_portd, &stats);
392 	rte_eth_stats_get(rxtx_porte, &stats2);
393 	if (stats.ipackets != 2 || stats.opackets != 2 ||
394 			stats.ibytes != 0 || stats.obytes != 0 ||
395 			stats.ierrors != 0 || stats.oerrors != 0) {
396 		printf("Error: port %d stats are not as expected\n",
397 				rxtx_portd);
398 		return TEST_FAILED;
399 	}
400 
401 	if (stats2.ipackets != 2 || stats2.opackets != 2 ||
402 			stats2.ibytes != 0 || stats2.obytes != 0 ||
403 			stats2.ierrors != 0 || stats2.oerrors != 0) {
404 		printf("Error: port %d stats are not as expected\n",
405 				rxtx_porte);
406 		return TEST_FAILED;
407 	}
408 
409 	rte_eth_dev_stop(rxtx_portd);
410 	rte_eth_dev_stop(rxtx_porte);
411 
412 	return TEST_SUCCESS;
413 }
414 
415 static void
416 test_cleanup_resources(void)
417 {
418 	int itr;
419 	for (itr = 0; itr < NUM_RINGS; itr++)
420 		rte_ring_free(rxtx[itr]);
421 
422 	rte_eth_dev_stop(tx_porta);
423 	rte_eth_dev_stop(rx_portb);
424 	rte_eth_dev_stop(rxtx_portc);
425 
426 	rte_mempool_free(mp);
427 	rte_vdev_uninit("net_ring_net_ringa");
428 	rte_vdev_uninit("net_ring_net_ringb");
429 	rte_vdev_uninit("net_ring_net_ringc");
430 	rte_vdev_uninit("net_ring_net_ringd");
431 	rte_vdev_uninit("net_ring_net_ringe");
432 }
433 
434 static int
435 test_pmd_ringcreate_setup(void)
436 {
437 	uint8_t nb_ports;
438 
439 	nb_ports = rte_eth_dev_count_avail();
440 	printf("nb_ports=%d\n", (int)nb_ports);
441 
442 	/*  create the rings and eth_rings in the test code.
443 	 *  This does not test the rte_pmd_ring_devinit function.
444 	 *
445 	 *  Test with the command line option --vdev=net_ring0 to test rte_pmd_ring_devinit.
446 	 */
447 	rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ);
448 	if (rxtx[0] == NULL) {
449 		printf("rte_ring_create R0 failed");
450 		return -1;
451 	}
452 
453 	rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ);
454 	if (rxtx[1] == NULL) {
455 		printf("rte_ring_create R1 failed");
456 		return -1;
457 	}
458 
459 	tx_porta = rte_eth_from_rings("net_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
460 	rx_portb = rte_eth_from_rings("net_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
461 	rxtx_portc = rte_eth_from_rings("net_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
462 	rxtx_portd = rte_eth_from_rings("net_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
463 	rxtx_porte = rte_eth_from_rings("net_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
464 
465 	printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n",
466 			tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte);
467 
468 	if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1)
469 			|| (rxtx_portd == -1) || (rxtx_porte == -1)) {
470 		printf("rte_eth_from rings failed\n");
471 		return -1;
472 	}
473 
474 	mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
475 			0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
476 	if (mp == NULL)
477 		return -1;
478 
479 	if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS)
480 			|| (rxtx_portc >= RTE_MAX_ETHPORTS)
481 			|| (rxtx_portd >= RTE_MAX_ETHPORTS)
482 			|| (rxtx_porte >= RTE_MAX_ETHPORTS)) {
483 		printf(" port exceed max eth ports\n");
484 		return -1;
485 	}
486 	return 0;
487 }
488 
489 static int
490 test_command_line_ring_port(void)
491 {
492 	int port, cmdl_port0 = -1;
493 	/* find a port created with the --vdev=net_ring0 command line option */
494 	RTE_ETH_FOREACH_DEV(port) {
495 		struct rte_eth_dev_info dev_info;
496 		rte_eth_dev_info_get(port, &dev_info);
497 		if (!strcmp(dev_info.driver_name, "Rings PMD")) {
498 			printf("found a command line ring port=%d\n", port);
499 			cmdl_port0 = port;
500 			break;
501 		}
502 	}
503 	if (cmdl_port0 != -1) {
504 		TEST_ASSERT((test_ethdev_configure_port(cmdl_port0) < 0),
505 				"test ethdev configure port cmdl_port0 is failed");
506 		TEST_ASSERT((test_send_basic_packets_port(cmdl_port0) < 0),
507 				"test send basic packets port cmdl_port0 is failed");
508 		TEST_ASSERT((test_stats_reset(cmdl_port0) < 0),
509 				"test stats reset cmdl_port0 is failed");
510 		TEST_ASSERT((test_get_stats(cmdl_port0) < 0),
511 				"test get stats cmdl_port0 is failed");
512 		rte_eth_dev_stop(cmdl_port0);
513 	}
514 	return TEST_SUCCESS;
515 }
516 
517 static int
518 test_ethdev_configure_ports(void)
519 {
520 	TEST_ASSERT((test_ethdev_configure_port(tx_porta) == 0),
521 			"test ethdev configure ports tx_porta is failed");
522 	TEST_ASSERT((test_ethdev_configure_port(rx_portb) == 0),
523 			"test ethdev configure ports rx_portb is failed");
524 	TEST_ASSERT((test_ethdev_configure_port(rxtx_portc) == 0),
525 			"test ethdev configure ports rxtx_portc is failed");
526 
527 	return TEST_SUCCESS;
528 }
529 
530 static int
531 test_get_stats_for_port(void)
532 {
533 	TEST_ASSERT(test_get_stats(rxtx_portc) == 0, "test get stats failed");
534 	return TEST_SUCCESS;
535 }
536 
537 static int
538 test_stats_reset_for_port(void)
539 {
540 	TEST_ASSERT(test_stats_reset(rxtx_portc) == 0, "test stats reset failed");
541 	return TEST_SUCCESS;
542 }
543 
544 static struct
545 unit_test_suite test_pmd_ring_suite  = {
546 	.setup = test_pmd_ringcreate_setup,
547 	.teardown = test_cleanup_resources,
548 	.suite_name = "Test Pmd Ring Unit Test Suite",
549 	.unit_test_cases = {
550 		TEST_CASE(test_ethdev_configure_ports),
551 		TEST_CASE(test_send_basic_packets),
552 		TEST_CASE(test_get_stats_for_port),
553 		TEST_CASE(test_stats_reset_for_port),
554 		TEST_CASE(test_pmd_ring_pair_create_attach),
555 		TEST_CASE(test_command_line_ring_port),
556 		TEST_CASES_END()
557 	}
558 };
559 
560 static int
561 test_pmd_ring(void)
562 {
563 	return unit_test_suite_runner(&test_pmd_ring_suite);
564 }
565 
566 REGISTER_TEST_COMMAND(ring_pmd_autotest, test_pmd_ring);
567