xref: /dpdk/app/graph/graph.c (revision 9236e5b31d909b45fa52c5e19adf02108a2052d1)
15c59002aSRakesh Kudurumalla /* SPDX-License-Identifier: BSD-3-Clause
25c59002aSRakesh Kudurumalla  * Copyright(c) 2023 Marvell.
35c59002aSRakesh Kudurumalla  */
45c59002aSRakesh Kudurumalla 
55c59002aSRakesh Kudurumalla #include <stdio.h>
65c59002aSRakesh Kudurumalla #include <stdlib.h>
75c59002aSRakesh Kudurumalla #include <string.h>
85c59002aSRakesh Kudurumalla 
95c59002aSRakesh Kudurumalla #include <cmdline_parse.h>
105c59002aSRakesh Kudurumalla #include <cmdline_parse_num.h>
115c59002aSRakesh Kudurumalla #include <cmdline_parse_string.h>
125c59002aSRakesh Kudurumalla #include <cmdline_socket.h>
135c59002aSRakesh Kudurumalla #include <rte_ethdev.h>
145c59002aSRakesh Kudurumalla #include <rte_graph_worker.h>
155c59002aSRakesh Kudurumalla #include <rte_log.h>
165c59002aSRakesh Kudurumalla 
175c59002aSRakesh Kudurumalla #include "graph_priv.h"
185c59002aSRakesh Kudurumalla #include "module_api.h"
195c59002aSRakesh Kudurumalla 
205c59002aSRakesh Kudurumalla #define RTE_LOGTYPE_APP_GRAPH RTE_LOGTYPE_USER1
215c59002aSRakesh Kudurumalla 
225c59002aSRakesh Kudurumalla static const char
230f32dac4SSunil Kumar Kori cmd_graph_help[] = "graph <usecases> coremask <bitmask> bsz <size> tmo <ns> "
245c59002aSRakesh Kudurumalla 		   "model <rtc | mcd | default> pcap_enable <0 | 1> num_pcap_pkts <num>"
255c59002aSRakesh Kudurumalla 		   "pcap_file <output_capture_file>";
265c59002aSRakesh Kudurumalla 
272c7debd9SRakesh Kudurumalla static const char * const supported_usecases[] = {"l3fwd", "l2fwd"};
285c59002aSRakesh Kudurumalla struct graph_config graph_config;
295c59002aSRakesh Kudurumalla bool graph_started;
305c59002aSRakesh Kudurumalla 
315c59002aSRakesh Kudurumalla /* Check the link rc of all ports in up to 9s, and print them finally */
325c59002aSRakesh Kudurumalla static void
335c59002aSRakesh Kudurumalla check_all_ports_link_status(uint32_t port_mask)
345c59002aSRakesh Kudurumalla {
355c59002aSRakesh Kudurumalla #define CHECK_INTERVAL 100 /* 100ms */
365c59002aSRakesh Kudurumalla #define MAX_CHECK_TIME 90  /* 9s (90 * 100ms) in total */
375c59002aSRakesh Kudurumalla 	char link_rc_text[RTE_ETH_LINK_MAX_STR_LEN];
385c59002aSRakesh Kudurumalla 	uint8_t count, all_ports_up, print_flag = 0;
395c59002aSRakesh Kudurumalla 	struct rte_eth_link link;
405c59002aSRakesh Kudurumalla 	uint16_t portid;
415c59002aSRakesh Kudurumalla 	int rc;
425c59002aSRakesh Kudurumalla 
435c59002aSRakesh Kudurumalla 	printf("\nChecking link status...");
445c59002aSRakesh Kudurumalla 	fflush(stdout);
455c59002aSRakesh Kudurumalla 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
465c59002aSRakesh Kudurumalla 		if (force_quit)
475c59002aSRakesh Kudurumalla 			return;
485c59002aSRakesh Kudurumalla 
495c59002aSRakesh Kudurumalla 		all_ports_up = 1;
505c59002aSRakesh Kudurumalla 		RTE_ETH_FOREACH_DEV(portid)
515c59002aSRakesh Kudurumalla 		{
525c59002aSRakesh Kudurumalla 			if (force_quit)
535c59002aSRakesh Kudurumalla 				return;
545c59002aSRakesh Kudurumalla 
555c59002aSRakesh Kudurumalla 			if ((port_mask & (1 << portid)) == 0)
565c59002aSRakesh Kudurumalla 				continue;
575c59002aSRakesh Kudurumalla 
585c59002aSRakesh Kudurumalla 			memset(&link, 0, sizeof(link));
595c59002aSRakesh Kudurumalla 			rc = rte_eth_link_get_nowait(portid, &link);
605c59002aSRakesh Kudurumalla 			if (rc < 0) {
615c59002aSRakesh Kudurumalla 				all_ports_up = 0;
625c59002aSRakesh Kudurumalla 				if (print_flag == 1)
635c59002aSRakesh Kudurumalla 					printf("Port %u link get failed: %s\n",
645c59002aSRakesh Kudurumalla 					       portid, rte_strerror(-rc));
655c59002aSRakesh Kudurumalla 				continue;
665c59002aSRakesh Kudurumalla 			}
675c59002aSRakesh Kudurumalla 
685c59002aSRakesh Kudurumalla 			/* Print link rc if flag set */
695c59002aSRakesh Kudurumalla 			if (print_flag == 1) {
705c59002aSRakesh Kudurumalla 				rte_eth_link_to_str(link_rc_text, sizeof(link_rc_text),
715c59002aSRakesh Kudurumalla 					&link);
725c59002aSRakesh Kudurumalla 				printf("Port %d %s\n", portid, link_rc_text);
735c59002aSRakesh Kudurumalla 				continue;
745c59002aSRakesh Kudurumalla 			}
755c59002aSRakesh Kudurumalla 
765c59002aSRakesh Kudurumalla 			/* Clear all_ports_up flag if any link down */
775c59002aSRakesh Kudurumalla 			if (link.link_status == RTE_ETH_LINK_DOWN) {
785c59002aSRakesh Kudurumalla 				all_ports_up = 0;
795c59002aSRakesh Kudurumalla 				break;
805c59002aSRakesh Kudurumalla 			}
815c59002aSRakesh Kudurumalla 		}
825c59002aSRakesh Kudurumalla 
835c59002aSRakesh Kudurumalla 		/* After finally printing all link rc, get out */
845c59002aSRakesh Kudurumalla 		if (print_flag == 1)
855c59002aSRakesh Kudurumalla 			break;
865c59002aSRakesh Kudurumalla 
875c59002aSRakesh Kudurumalla 		if (all_ports_up == 0) {
885c59002aSRakesh Kudurumalla 			printf(".");
895c59002aSRakesh Kudurumalla 			fflush(stdout);
905c59002aSRakesh Kudurumalla 			rte_delay_ms(CHECK_INTERVAL);
915c59002aSRakesh Kudurumalla 		}
925c59002aSRakesh Kudurumalla 
935c59002aSRakesh Kudurumalla 		/* Set the print_flag if all ports up or timeout */
945c59002aSRakesh Kudurumalla 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
955c59002aSRakesh Kudurumalla 			print_flag = 1;
965c59002aSRakesh Kudurumalla 			printf("Done\n");
975c59002aSRakesh Kudurumalla 		}
985c59002aSRakesh Kudurumalla 	}
995c59002aSRakesh Kudurumalla }
1005c59002aSRakesh Kudurumalla 
1015c59002aSRakesh Kudurumalla static bool
1025c59002aSRakesh Kudurumalla parser_usecases_read(char *usecases)
1035c59002aSRakesh Kudurumalla {
1045c59002aSRakesh Kudurumalla 	bool valid = false;
1055c59002aSRakesh Kudurumalla 	uint32_t i, j = 0;
106*9236e5b3SStephen Hemminger 	char *token, *saveptr = NULL;
1075c59002aSRakesh Kudurumalla 
108*9236e5b3SStephen Hemminger 	token = strtok_r(usecases, ",", &saveptr);
1095c59002aSRakesh Kudurumalla 	while (token != NULL) {
1105c59002aSRakesh Kudurumalla 		for (i = 0; i < RTE_DIM(supported_usecases); i++) {
1115c59002aSRakesh Kudurumalla 			if (strcmp(supported_usecases[i], token) == 0) {
1125c59002aSRakesh Kudurumalla 				graph_config.usecases[j].enabled = true;
1135c59002aSRakesh Kudurumalla 				rte_strscpy(graph_config.usecases[j].name, token, 31);
1145c59002aSRakesh Kudurumalla 				valid = true;
1155c59002aSRakesh Kudurumalla 				j++;
1165c59002aSRakesh Kudurumalla 				break;
1175c59002aSRakesh Kudurumalla 			}
1185c59002aSRakesh Kudurumalla 		}
119*9236e5b3SStephen Hemminger 		token = strtok_r(NULL, ",", &saveptr);
1205c59002aSRakesh Kudurumalla 	}
1215c59002aSRakesh Kudurumalla 
1225c59002aSRakesh Kudurumalla 	return valid;
1235c59002aSRakesh Kudurumalla }
1245c59002aSRakesh Kudurumalla 
1255c59002aSRakesh Kudurumalla static uint64_t
1265c59002aSRakesh Kudurumalla graph_worker_count_get(void)
1275c59002aSRakesh Kudurumalla {
1285c59002aSRakesh Kudurumalla 	uint64_t nb_worker = 0;
1295c59002aSRakesh Kudurumalla 	uint64_t coremask;
1305c59002aSRakesh Kudurumalla 
1315c59002aSRakesh Kudurumalla 	coremask = graph_config.params.coremask;
1325c59002aSRakesh Kudurumalla 	while (coremask) {
1335c59002aSRakesh Kudurumalla 		if (coremask & 0x1)
1345c59002aSRakesh Kudurumalla 			nb_worker++;
1355c59002aSRakesh Kudurumalla 
1365c59002aSRakesh Kudurumalla 		coremask = (coremask >> 1);
1375c59002aSRakesh Kudurumalla 	}
1385c59002aSRakesh Kudurumalla 
1395c59002aSRakesh Kudurumalla 	return nb_worker;
1405c59002aSRakesh Kudurumalla }
1415c59002aSRakesh Kudurumalla 
1425c59002aSRakesh Kudurumalla static struct rte_node_ethdev_config *
1435c59002aSRakesh Kudurumalla graph_rxtx_node_config_get(uint32_t *num_conf, uint32_t *num_graphs)
1445c59002aSRakesh Kudurumalla {
1455c59002aSRakesh Kudurumalla 	uint32_t n_tx_queue, nb_conf = 0, lcore_id;
1465c59002aSRakesh Kudurumalla 	uint16_t queueid, portid, nb_graphs = 0;
1475c59002aSRakesh Kudurumalla 	uint8_t nb_rx_queue, queue;
1485c59002aSRakesh Kudurumalla 	struct lcore_conf *qconf;
1495c59002aSRakesh Kudurumalla 
1505c59002aSRakesh Kudurumalla 	n_tx_queue = graph_worker_count_get();
1515c59002aSRakesh Kudurumalla 	if (n_tx_queue > RTE_MAX_ETHPORTS)
1525c59002aSRakesh Kudurumalla 		n_tx_queue = RTE_MAX_ETHPORTS;
1535c59002aSRakesh Kudurumalla 
1545c59002aSRakesh Kudurumalla 	RTE_ETH_FOREACH_DEV(portid) {
1555c59002aSRakesh Kudurumalla 		/* Skip ports that are not enabled */
1565c59002aSRakesh Kudurumalla 		if ((enabled_port_mask & (1 << portid)) == 0) {
1575c59002aSRakesh Kudurumalla 			printf("\nSkipping disabled port %d\n", portid);
1585c59002aSRakesh Kudurumalla 			continue;
1595c59002aSRakesh Kudurumalla 		}
1605c59002aSRakesh Kudurumalla 
1615c59002aSRakesh Kudurumalla 		nb_rx_queue = ethdev_rx_num_rx_queues_get(portid);
1625c59002aSRakesh Kudurumalla 
1635c59002aSRakesh Kudurumalla 		/* Setup ethdev node config */
1645c59002aSRakesh Kudurumalla 		ethdev_conf[nb_conf].port_id = portid;
1655c59002aSRakesh Kudurumalla 		ethdev_conf[nb_conf].num_rx_queues = nb_rx_queue;
1665c59002aSRakesh Kudurumalla 		ethdev_conf[nb_conf].num_tx_queues = n_tx_queue;
1675c59002aSRakesh Kudurumalla 		ethdev_conf[nb_conf].mp = ethdev_mempool_list_by_portid(portid);
1685c59002aSRakesh Kudurumalla 		ethdev_conf[nb_conf].mp_count = 1; /* Check with pools */
1695c59002aSRakesh Kudurumalla 
1705c59002aSRakesh Kudurumalla 		nb_conf++;
1715c59002aSRakesh Kudurumalla 	}
1725c59002aSRakesh Kudurumalla 
1735c59002aSRakesh Kudurumalla 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1745c59002aSRakesh Kudurumalla 		if (rte_lcore_is_enabled(lcore_id) == 0)
1755c59002aSRakesh Kudurumalla 			continue;
1765c59002aSRakesh Kudurumalla 
1775c59002aSRakesh Kudurumalla 		qconf = &lcore_conf[lcore_id];
1785c59002aSRakesh Kudurumalla 		printf("\nInitializing rx queues on lcore %u ... ", lcore_id);
1795c59002aSRakesh Kudurumalla 		fflush(stdout);
1805c59002aSRakesh Kudurumalla 
1815c59002aSRakesh Kudurumalla 		/* Init RX queues */
1825c59002aSRakesh Kudurumalla 		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
1835c59002aSRakesh Kudurumalla 			portid = qconf->rx_queue_list[queue].port_id;
1845c59002aSRakesh Kudurumalla 			queueid = qconf->rx_queue_list[queue].queue_id;
1855c59002aSRakesh Kudurumalla 
1865c59002aSRakesh Kudurumalla 			/* Add this queue node to its graph */
1875c59002aSRakesh Kudurumalla 			snprintf(qconf->rx_queue_list[queue].node_name, RTE_NODE_NAMESIZE,
1885c59002aSRakesh Kudurumalla 				 "ethdev_rx-%u-%u", portid, queueid);
1895c59002aSRakesh Kudurumalla 		}
1905c59002aSRakesh Kudurumalla 		if (qconf->n_rx_queue)
1915c59002aSRakesh Kudurumalla 			nb_graphs++;
1925c59002aSRakesh Kudurumalla 	}
1935c59002aSRakesh Kudurumalla 
1945c59002aSRakesh Kudurumalla 	printf("\n");
1955c59002aSRakesh Kudurumalla 
1965c59002aSRakesh Kudurumalla 	ethdev_start();
1975c59002aSRakesh Kudurumalla 	check_all_ports_link_status(enabled_port_mask);
1985c59002aSRakesh Kudurumalla 
1995c59002aSRakesh Kudurumalla 	*num_conf = nb_conf;
2005c59002aSRakesh Kudurumalla 	*num_graphs = nb_graphs;
2015c59002aSRakesh Kudurumalla 	return ethdev_conf;
2025c59002aSRakesh Kudurumalla }
2035c59002aSRakesh Kudurumalla 
2045c59002aSRakesh Kudurumalla static void
2055c59002aSRakesh Kudurumalla graph_stats_print_to_file(void)
2065c59002aSRakesh Kudurumalla {
2075c59002aSRakesh Kudurumalla 	struct rte_graph_cluster_stats_param s_param;
2085c59002aSRakesh Kudurumalla 	struct rte_graph_cluster_stats *stats;
2095c59002aSRakesh Kudurumalla 	const char *pattern = "worker_*";
2105c59002aSRakesh Kudurumalla 	FILE *fp = NULL;
2115c59002aSRakesh Kudurumalla 	size_t sz, len;
2125c59002aSRakesh Kudurumalla 
2135c59002aSRakesh Kudurumalla 	/* Prepare stats object */
2145c59002aSRakesh Kudurumalla 	fp = fopen("/tmp/graph_stats.txt", "w+");
2155c59002aSRakesh Kudurumalla 	if (fp == NULL)
2165c59002aSRakesh Kudurumalla 		rte_exit(EXIT_FAILURE, "Error in opening stats file\n");
2175c59002aSRakesh Kudurumalla 
2185c59002aSRakesh Kudurumalla 	memset(&s_param, 0, sizeof(s_param));
2195c59002aSRakesh Kudurumalla 	s_param.f = fp;
2205c59002aSRakesh Kudurumalla 	s_param.socket_id = SOCKET_ID_ANY;
2215c59002aSRakesh Kudurumalla 	s_param.graph_patterns = &pattern;
2225c59002aSRakesh Kudurumalla 	s_param.nb_graph_patterns = 1;
2235c59002aSRakesh Kudurumalla 
2245c59002aSRakesh Kudurumalla 	stats = rte_graph_cluster_stats_create(&s_param);
2255c59002aSRakesh Kudurumalla 	if (stats == NULL)
2265c59002aSRakesh Kudurumalla 		rte_exit(EXIT_FAILURE, "Unable to create stats object\n");
2275c59002aSRakesh Kudurumalla 
2285c59002aSRakesh Kudurumalla 	/* Clear screen and move to top left */
2295c59002aSRakesh Kudurumalla 	rte_graph_cluster_stats_get(stats, 0);
2305c59002aSRakesh Kudurumalla 	rte_delay_ms(1E3);
2315c59002aSRakesh Kudurumalla 
2325c59002aSRakesh Kudurumalla 	fseek(fp, 0L, SEEK_END);
2335c59002aSRakesh Kudurumalla 	sz = ftell(fp);
2345c59002aSRakesh Kudurumalla 	fseek(fp, 0L, SEEK_SET);
2355c59002aSRakesh Kudurumalla 
2365c59002aSRakesh Kudurumalla 	len = strlen(conn->msg_out);
2375c59002aSRakesh Kudurumalla 	conn->msg_out += len;
2385c59002aSRakesh Kudurumalla 
2395c59002aSRakesh Kudurumalla 	sz = fread(conn->msg_out, sizeof(char), sz, fp);
2405c59002aSRakesh Kudurumalla 	len = strlen(conn->msg_out);
2415c59002aSRakesh Kudurumalla 	conn->msg_out_len_max -= len;
2425c59002aSRakesh Kudurumalla 	rte_graph_cluster_stats_destroy(stats);
2435c59002aSRakesh Kudurumalla 
2445c59002aSRakesh Kudurumalla 	fclose(fp);
2455c59002aSRakesh Kudurumalla }
2465c59002aSRakesh Kudurumalla 
2470f32dac4SSunil Kumar Kori void
2480f32dac4SSunil Kumar Kori cmd_graph_stats_show_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
2495c59002aSRakesh Kudurumalla 		__rte_unused void *data)
2505c59002aSRakesh Kudurumalla {
2515c59002aSRakesh Kudurumalla 	graph_stats_print_to_file();
2525c59002aSRakesh Kudurumalla }
2535c59002aSRakesh Kudurumalla 
2545c59002aSRakesh Kudurumalla bool
2555c59002aSRakesh Kudurumalla graph_status_get(void)
2565c59002aSRakesh Kudurumalla {
2575c59002aSRakesh Kudurumalla 	return graph_started;
2585c59002aSRakesh Kudurumalla }
2595c59002aSRakesh Kudurumalla 
2600f32dac4SSunil Kumar Kori void
2610f32dac4SSunil Kumar Kori cmd_graph_start_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
2625c59002aSRakesh Kudurumalla 		__rte_unused void *data)
2635c59002aSRakesh Kudurumalla {
2645c59002aSRakesh Kudurumalla 	struct rte_node_ethdev_config *conf;
2655c59002aSRakesh Kudurumalla 	uint32_t nb_graphs = 0, nb_conf, i;
2665c59002aSRakesh Kudurumalla 	int rc = -EINVAL;
2675c59002aSRakesh Kudurumalla 
2685c59002aSRakesh Kudurumalla 	conf = graph_rxtx_node_config_get(&nb_conf, &nb_graphs);
2695c59002aSRakesh Kudurumalla 	for (i = 0; i < MAX_GRAPH_USECASES; i++) {
2705c59002aSRakesh Kudurumalla 		if (!strcmp(graph_config.usecases[i].name, "l3fwd")) {
2715c59002aSRakesh Kudurumalla 			if (graph_config.usecases[i].enabled) {
27234c0c38aSRakesh Kudurumalla 				rc  = usecase_l3fwd_configure(conf, nb_conf, nb_graphs);
2735c59002aSRakesh Kudurumalla 				break;
2745c59002aSRakesh Kudurumalla 			}
2755c59002aSRakesh Kudurumalla 		}
2762c7debd9SRakesh Kudurumalla 		if (!strcmp(graph_config.usecases[i].name, "l2fwd")) {
2772c7debd9SRakesh Kudurumalla 			if (graph_config.usecases[i].enabled) {
2782c7debd9SRakesh Kudurumalla 				rc  = usecase_l2fwd_configure(conf, nb_conf, nb_graphs);
2792c7debd9SRakesh Kudurumalla 				break;
2802c7debd9SRakesh Kudurumalla 			}
2812c7debd9SRakesh Kudurumalla 		}
2825c59002aSRakesh Kudurumalla 	}
2835c59002aSRakesh Kudurumalla 
2845c59002aSRakesh Kudurumalla 	if (!rc)
2855c59002aSRakesh Kudurumalla 		graph_started = true;
2865c59002aSRakesh Kudurumalla }
2875c59002aSRakesh Kudurumalla 
2885c59002aSRakesh Kudurumalla static int
2895c59002aSRakesh Kudurumalla graph_config_add(char *usecases, struct graph_config *config)
2905c59002aSRakesh Kudurumalla {
2915c59002aSRakesh Kudurumalla 	uint64_t lcore_id, core_num;
2925c59002aSRakesh Kudurumalla 	uint64_t eal_coremask = 0;
2935c59002aSRakesh Kudurumalla 
2945c59002aSRakesh Kudurumalla 	if (!parser_usecases_read(usecases))
2955c59002aSRakesh Kudurumalla 		return -EINVAL;
2965c59002aSRakesh Kudurumalla 
2975c59002aSRakesh Kudurumalla 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
2985c59002aSRakesh Kudurumalla 		if (rte_lcore_is_enabled(lcore_id))
2995c59002aSRakesh Kudurumalla 			eal_coremask |= RTE_BIT64(lcore_id);
3005c59002aSRakesh Kudurumalla 	}
3015c59002aSRakesh Kudurumalla 
3025c59002aSRakesh Kudurumalla 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
3035c59002aSRakesh Kudurumalla 		core_num = 1 << lcore_id;
3045c59002aSRakesh Kudurumalla 		if (config->params.coremask & core_num) {
3055c59002aSRakesh Kudurumalla 			if (eal_coremask & core_num)
3065c59002aSRakesh Kudurumalla 				continue;
3075c59002aSRakesh Kudurumalla 			else
3085c59002aSRakesh Kudurumalla 				return -EINVAL;
3095c59002aSRakesh Kudurumalla 		}
3105c59002aSRakesh Kudurumalla 	}
3115c59002aSRakesh Kudurumalla 
3125c59002aSRakesh Kudurumalla 	graph_config.params.bsz = config->params.bsz;
3135c59002aSRakesh Kudurumalla 	graph_config.params.tmo = config->params.tmo;
3145c59002aSRakesh Kudurumalla 	graph_config.params.coremask = config->params.coremask;
3155c59002aSRakesh Kudurumalla 	graph_config.model = config->model;
3165c59002aSRakesh Kudurumalla 	graph_config.pcap_ena = config->pcap_ena;
3175c59002aSRakesh Kudurumalla 	graph_config.num_pcap_pkts = config->num_pcap_pkts;
3185c59002aSRakesh Kudurumalla 	graph_config.pcap_file = strdup(config->pcap_file);
3195c59002aSRakesh Kudurumalla 
3205c59002aSRakesh Kudurumalla 	return 0;
3215c59002aSRakesh Kudurumalla }
3225c59002aSRakesh Kudurumalla 
3235c59002aSRakesh Kudurumalla void
3245c59002aSRakesh Kudurumalla graph_pcap_config_get(uint8_t *pcap_ena, uint64_t *num_pkts, char **file)
3255c59002aSRakesh Kudurumalla {
3265c59002aSRakesh Kudurumalla 
3275c59002aSRakesh Kudurumalla 	*pcap_ena = graph_config.pcap_ena;
3285c59002aSRakesh Kudurumalla 	*num_pkts = graph_config.num_pcap_pkts;
3295c59002aSRakesh Kudurumalla 	*file = graph_config.pcap_file;
3305c59002aSRakesh Kudurumalla }
3315c59002aSRakesh Kudurumalla 
3325c59002aSRakesh Kudurumalla int
3335c59002aSRakesh Kudurumalla graph_walk_start(void *conf)
3345c59002aSRakesh Kudurumalla {
3355c59002aSRakesh Kudurumalla 	struct lcore_conf *qconf;
3365c59002aSRakesh Kudurumalla 	struct rte_graph *graph;
3375c59002aSRakesh Kudurumalla 	uint32_t lcore_id;
3385c59002aSRakesh Kudurumalla 
3395c59002aSRakesh Kudurumalla 	RTE_SET_USED(conf);
3405c59002aSRakesh Kudurumalla 
3415c59002aSRakesh Kudurumalla 	lcore_id = rte_lcore_id();
3425c59002aSRakesh Kudurumalla 	qconf = &lcore_conf[lcore_id];
3435c59002aSRakesh Kudurumalla 	graph = qconf->graph;
3445c59002aSRakesh Kudurumalla 
3455c59002aSRakesh Kudurumalla 	if (!graph) {
3465c59002aSRakesh Kudurumalla 		RTE_LOG(INFO, APP_GRAPH, "Lcore %u has nothing to do\n", lcore_id);
3475c59002aSRakesh Kudurumalla 		return 0;
3485c59002aSRakesh Kudurumalla 	}
3495c59002aSRakesh Kudurumalla 
3505c59002aSRakesh Kudurumalla 	RTE_LOG(INFO, APP_GRAPH, "Entering main loop on lcore %u, graph %s(%p)\n", lcore_id,
3515c59002aSRakesh Kudurumalla 		qconf->name, graph);
3525c59002aSRakesh Kudurumalla 
3535c59002aSRakesh Kudurumalla 	while (likely(!force_quit))
3545c59002aSRakesh Kudurumalla 		rte_graph_walk(graph);
3555c59002aSRakesh Kudurumalla 
3565c59002aSRakesh Kudurumalla 	return 0;
3575c59002aSRakesh Kudurumalla }
3585c59002aSRakesh Kudurumalla 
3595c59002aSRakesh Kudurumalla void
3605c59002aSRakesh Kudurumalla graph_stats_print(void)
3615c59002aSRakesh Kudurumalla {
3625c59002aSRakesh Kudurumalla 	const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'};
3635c59002aSRakesh Kudurumalla 	const char clr[] = {27, '[', '2', 'J', '\0'};
3645c59002aSRakesh Kudurumalla 	struct rte_graph_cluster_stats_param s_param;
3655c59002aSRakesh Kudurumalla 	struct rte_graph_cluster_stats *stats;
3665c59002aSRakesh Kudurumalla 	const char *pattern = "worker_*";
3675c59002aSRakesh Kudurumalla 
3685c59002aSRakesh Kudurumalla 	/* Prepare stats object */
3695c59002aSRakesh Kudurumalla 	memset(&s_param, 0, sizeof(s_param));
3705c59002aSRakesh Kudurumalla 	s_param.f = stdout;
3715c59002aSRakesh Kudurumalla 	s_param.socket_id = SOCKET_ID_ANY;
3725c59002aSRakesh Kudurumalla 	s_param.graph_patterns = &pattern;
3735c59002aSRakesh Kudurumalla 	s_param.nb_graph_patterns = 1;
3745c59002aSRakesh Kudurumalla 
3755c59002aSRakesh Kudurumalla 	stats = rte_graph_cluster_stats_create(&s_param);
3765c59002aSRakesh Kudurumalla 	if (stats == NULL)
3775c59002aSRakesh Kudurumalla 		rte_exit(EXIT_FAILURE, "Unable to create stats object\n");
3785c59002aSRakesh Kudurumalla 
3795c59002aSRakesh Kudurumalla 	while (!force_quit) {
3805c59002aSRakesh Kudurumalla 		/* Clear screen and move to top left */
3815c59002aSRakesh Kudurumalla 		printf("%s%s", clr, topLeft);
3825c59002aSRakesh Kudurumalla 		rte_graph_cluster_stats_get(stats, 0);
3835c59002aSRakesh Kudurumalla 		rte_delay_ms(1E3);
3845c59002aSRakesh Kudurumalla 		if (app_graph_exit())
3855c59002aSRakesh Kudurumalla 			force_quit = true;
3865c59002aSRakesh Kudurumalla 	}
3875c59002aSRakesh Kudurumalla 
3885c59002aSRakesh Kudurumalla 	rte_graph_cluster_stats_destroy(stats);
3895c59002aSRakesh Kudurumalla }
3905c59002aSRakesh Kudurumalla 
3915c59002aSRakesh Kudurumalla uint64_t
3925c59002aSRakesh Kudurumalla graph_coremask_get(void)
3935c59002aSRakesh Kudurumalla {
3945c59002aSRakesh Kudurumalla 	return graph_config.params.coremask;
3955c59002aSRakesh Kudurumalla }
3965c59002aSRakesh Kudurumalla 
3970f32dac4SSunil Kumar Kori void
3980f32dac4SSunil Kumar Kori cmd_graph_parsed(void *parsed_result, __rte_unused struct cmdline *cl, __rte_unused void *data)
3995c59002aSRakesh Kudurumalla {
4000f32dac4SSunil Kumar Kori 	struct cmd_graph_result *res = parsed_result;
4015c59002aSRakesh Kudurumalla 	struct graph_config config;
4025c59002aSRakesh Kudurumalla 	char *model_name;
4035c59002aSRakesh Kudurumalla 	uint8_t model;
4045c59002aSRakesh Kudurumalla 	int rc;
4055c59002aSRakesh Kudurumalla 
4065c59002aSRakesh Kudurumalla 	model_name = res->model_name;
4075c59002aSRakesh Kudurumalla 	if (strcmp(model_name, "default") == 0) {
4085c59002aSRakesh Kudurumalla 		model = GRAPH_MODEL_RTC;
4095c59002aSRakesh Kudurumalla 	} else if (strcmp(model_name, "rtc") == 0) {
4105c59002aSRakesh Kudurumalla 		model = GRAPH_MODEL_RTC;
4115c59002aSRakesh Kudurumalla 	} else if (strcmp(model_name, "mcd") == 0) {
4125c59002aSRakesh Kudurumalla 		model = GRAPH_MODEL_MCD;
4135c59002aSRakesh Kudurumalla 	} else {
4145c59002aSRakesh Kudurumalla 		printf(MSG_ARG_NOT_FOUND, "model arguments");
4155c59002aSRakesh Kudurumalla 		return;
4165c59002aSRakesh Kudurumalla 	}
4175c59002aSRakesh Kudurumalla 
4185c59002aSRakesh Kudurumalla 	config.params.bsz = res->size;
4195c59002aSRakesh Kudurumalla 	config.params.tmo = res->ns;
4205c59002aSRakesh Kudurumalla 	config.params.coremask = res->mask;
4215c59002aSRakesh Kudurumalla 	config.model = model;
4225c59002aSRakesh Kudurumalla 	config.pcap_ena = res->pcap_ena;
4235c59002aSRakesh Kudurumalla 	config.num_pcap_pkts = res->num_pcap_pkts;
4245c59002aSRakesh Kudurumalla 	config.pcap_file = res->pcap_file;
4255c59002aSRakesh Kudurumalla 	rc = graph_config_add(res->usecase, &config);
4265c59002aSRakesh Kudurumalla 	if (rc < 0) {
4275c59002aSRakesh Kudurumalla 		cli_exit();
4285c59002aSRakesh Kudurumalla 		printf(MSG_CMD_FAIL, res->graph);
4295c59002aSRakesh Kudurumalla 		rte_exit(EXIT_FAILURE, "coremask is Invalid\n");
4305c59002aSRakesh Kudurumalla 	}
4315c59002aSRakesh Kudurumalla }
4325c59002aSRakesh Kudurumalla 
4330f32dac4SSunil Kumar Kori void
4340f32dac4SSunil Kumar Kori cmd_help_graph_parsed(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl,
4355c59002aSRakesh Kudurumalla 		      __rte_unused void *data)
4365c59002aSRakesh Kudurumalla {
4375c59002aSRakesh Kudurumalla 	size_t len;
4385c59002aSRakesh Kudurumalla 
4395c59002aSRakesh Kudurumalla 	len = strlen(conn->msg_out);
4405c59002aSRakesh Kudurumalla 	conn->msg_out += len;
4415c59002aSRakesh Kudurumalla 	snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n%s\n%s\n",
4425c59002aSRakesh Kudurumalla 		 "----------------------------- graph command help -----------------------------",
4435c59002aSRakesh Kudurumalla 		 cmd_graph_help, "graph start", "graph stats show");
4445c59002aSRakesh Kudurumalla 
4455c59002aSRakesh Kudurumalla 	len = strlen(conn->msg_out);
4465c59002aSRakesh Kudurumalla 	conn->msg_out_len_max -= len;
4475c59002aSRakesh Kudurumalla }
448