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