From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DDEC3425F4; Thu, 21 Sep 2023 12:10:07 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3D91D40ED6; Thu, 21 Sep 2023 12:09:06 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 6CCC040E03 for ; Thu, 21 Sep 2023 12:09:00 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 38L7Poat001328 for ; Thu, 21 Sep 2023 03:08:59 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=0wgYBut9XTcU2BMak+8C6Uoj8jAg+9uR5fM2a42onIE=; b=OOeGm8xSJzooulTMQ7w+LnlNGeLwozgSWQVgiguAsVQT7ao9jgEAJ/xv4hp4d4rD6uwH KqPypn5+HG0zHldfEpW9E8YKNdaJDhGGwGtIeqdwQd7d/myEikubglMgLMgxwmAPlvhb Iyx76xE04hNmia/sYadVnuTR9FH7DL9z0zH7bewJe40z33AdgzrJJJ8vhJJNIjKKsjLZ z6ORky3sMv5qjMQ3Yz2f5dfIMwM0wyk7NBOEHHCaXB6BGzBXpJGWhiDU0YKqKvV392uO IuJaVQPIdPqPWKXs7NQI7MqXMgn9nl6I/1miQBjYRbUyJNHNBN2teMDe0xyzpfNZS03Z mQ== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3t7u4ddk23-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 21 Sep 2023 03:08:59 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Thu, 21 Sep 2023 03:08:57 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Thu, 21 Sep 2023 03:08:57 -0700 Received: from localhost.localdomain (unknown [10.28.34.25]) by maili.marvell.com (Postfix) with ESMTP id 573AF5B693B; Thu, 21 Sep 2023 03:08:56 -0700 (PDT) From: To: Sunil Kumar Kori , Rakesh Kudurumalla CC: Subject: [PATCH v5 10/12] app/graph: add graph command line interfaces Date: Thu, 21 Sep 2023 15:38:30 +0530 Message-ID: <20230921100832.2036256-11-skori@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230921100832.2036256-1-skori@marvell.com> References: <20230919160455.1678716-1-skori@marvell.com> <20230921100832.2036256-1-skori@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-ORIG-GUID: qqru8__P1gb1S7QpT_PEbk6wxr8un18w X-Proofpoint-GUID: qqru8__P1gb1S7QpT_PEbk6wxr8un18w X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-09-21_07,2023-09-20_01,2023-05-22_02 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Rakesh Kudurumalla It adds graph module to create a graph for a given usecase like l3fwd. Following commands are exposed: - graph [bsz ] [tmo ] [coremask ] \ model pcap_enable <0 | 1> num_pcap_pkts \ pcap_file - graph start - graph stats show - help graph Signed-off-by: Sunil Kumar Kori Signed-off-by: Rakesh Kudurumalla --- app/graph/cli.c | 4 + app/graph/graph.c | 537 +++++++++++++++++++++++++++++++++++++ app/graph/graph.h | 20 ++ app/graph/graph_priv.h | 70 +++++ app/graph/meson.build | 1 + app/graph/module_api.h | 1 + doc/guides/tools/graph.rst | 19 +- 7 files changed, 650 insertions(+), 2 deletions(-) create mode 100644 app/graph/graph.c create mode 100644 app/graph/graph.h create mode 100644 app/graph/graph_priv.h diff --git a/app/graph/cli.c b/app/graph/cli.c index e947f61ee4..c43af5925c 100644 --- a/app/graph/cli.c +++ b/app/graph/cli.c @@ -20,6 +20,10 @@ #define MAX_LINE_SIZE 2048 cmdline_parse_ctx_t modules_ctx[] = { + (cmdline_parse_inst_t *)&graph_config_cmd_ctx, + (cmdline_parse_inst_t *)&graph_start_cmd_ctx, + (cmdline_parse_inst_t *)&graph_stats_cmd_ctx, + (cmdline_parse_inst_t *)&graph_help_cmd_ctx, (cmdline_parse_inst_t *)&mempool_config_cmd_ctx, (cmdline_parse_inst_t *)&mempool_help_cmd_ctx, (cmdline_parse_inst_t *)ðdev_show_cmd_ctx, diff --git a/app/graph/graph.c b/app/graph/graph.c new file mode 100644 index 0000000000..c3ed2c3f2d --- /dev/null +++ b/app/graph/graph.c @@ -0,0 +1,537 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "graph_priv.h" +#include "module_api.h" + +#define RTE_LOGTYPE_APP_GRAPH RTE_LOGTYPE_USER1 + +static const char +cmd_graph_help[] = "graph bsz tmo coremask " + "model pcap_enable <0 | 1> num_pcap_pkts " + "pcap_file "; + +static const char * const supported_usecases[] = {"l3fwd"}; +struct graph_config graph_config; + +/* Check the link rc of all ports in up to 9s, and print them finally */ +static void +check_all_ports_link_status(uint32_t port_mask) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ + char link_rc_text[RTE_ETH_LINK_MAX_STR_LEN]; + uint8_t count, all_ports_up, print_flag = 0; + struct rte_eth_link link; + uint16_t portid; + int rc; + + printf("\nChecking link rc"); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + if (force_quit) + return; + + all_ports_up = 1; + RTE_ETH_FOREACH_DEV(portid) + { + if (force_quit) + return; + + if ((port_mask & (1 << portid)) == 0) + continue; + + memset(&link, 0, sizeof(link)); + rc = rte_eth_link_get_nowait(portid, &link); + if (rc < 0) { + all_ports_up = 0; + if (print_flag == 1) + printf("Port %u link get failed: %s\n", + portid, rte_strerror(-rc)); + continue; + } + + /* Print link rc if flag set */ + if (print_flag == 1) { + rte_eth_link_to_str(link_rc_text, sizeof(link_rc_text), + &link); + printf("Port %d %s\n", portid, link_rc_text); + continue; + } + + /* Clear all_ports_up flag if any link down */ + if (link.link_status == RTE_ETH_LINK_DOWN) { + all_ports_up = 0; + break; + } + } + + /* After finally printing all link rc, get out */ + if (print_flag == 1) + break; + + if (all_ports_up == 0) { + printf("."); + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + + /* Set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { + print_flag = 1; + printf("Done\n"); + } + } +} + +static bool +parser_usecases_read(char *usecases) +{ + bool valid = false; + uint32_t i, j = 0; + char *token; + + token = strtok(usecases, ","); + while (token != NULL) { + for (i = 0; i < RTE_DIM(supported_usecases); i++) { + if (strcmp(supported_usecases[i], token) == 0) { + graph_config.usecases[j].enabled = true; + strcpy(graph_config.usecases[j].name, token); + valid = true; + j++; + break; + } + } + token = strtok(NULL, ","); + } + + return valid; +} + +static uint64_t +graph_worker_count_get(void) +{ + uint64_t nb_worker = 0; + uint64_t coremask; + + coremask = graph_config.params.coremask; + while (coremask) { + if (coremask & 0x1) + nb_worker++; + + coremask = (coremask >> 1); + } + + return nb_worker; +} + +static struct rte_node_ethdev_config * +graph_rxtx_node_config_get(uint32_t *num_conf, uint32_t *num_graphs) +{ + uint32_t n_tx_queue, nb_conf = 0, lcore_id; + uint16_t queueid, portid, nb_graphs = 0; + uint8_t nb_rx_queue, queue; + struct lcore_conf *qconf; + + n_tx_queue = graph_worker_count_get(); + if (n_tx_queue > RTE_MAX_ETHPORTS) + n_tx_queue = RTE_MAX_ETHPORTS; + + RTE_ETH_FOREACH_DEV(portid) { + /* Skip ports that are not enabled */ + if ((enabled_port_mask & (1 << portid)) == 0) { + printf("\nSkipping disabled port %d\n", portid); + continue; + } + + nb_rx_queue = ethdev_rx_num_rx_queues_get(portid); + + /* Setup ethdev node config */ + ethdev_conf[nb_conf].port_id = portid; + ethdev_conf[nb_conf].num_rx_queues = nb_rx_queue; + ethdev_conf[nb_conf].num_tx_queues = n_tx_queue; + ethdev_conf[nb_conf].mp = ethdev_mempool_list_by_portid(portid); + ethdev_conf[nb_conf].mp_count = 1; /* Check with pools */ + + nb_conf++; + } + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (rte_lcore_is_enabled(lcore_id) == 0) + continue; + + qconf = &lcore_conf[lcore_id]; + printf("\nInitializing rx queues on lcore %u ... ", lcore_id); + fflush(stdout); + + /* Init RX queues */ + for (queue = 0; queue < qconf->n_rx_queue; ++queue) { + portid = qconf->rx_queue_list[queue].port_id; + queueid = qconf->rx_queue_list[queue].queue_id; + + /* Add this queue node to its graph */ + snprintf(qconf->rx_queue_list[queue].node_name, RTE_NODE_NAMESIZE, + "ethdev_rx-%u-%u", portid, queueid); + } + if (qconf->n_rx_queue) + nb_graphs++; + } + + printf("\n"); + + ethdev_start(); + check_all_ports_link_status(enabled_port_mask); + + *num_conf = nb_conf; + *num_graphs = nb_graphs; + return ethdev_conf; +} + +static void +graph_stats_print_to_file(void) +{ + struct rte_graph_cluster_stats_param s_param; + struct rte_graph_cluster_stats *stats; + const char *pattern = "worker_*"; + FILE *fp = NULL; + size_t sz, len; + + /* Prepare stats object */ + fp = fopen("/tmp/graph_stats.txt", "w+"); + memset(&s_param, 0, sizeof(s_param)); + s_param.f = fp; + s_param.socket_id = SOCKET_ID_ANY; + s_param.graph_patterns = &pattern; + s_param.nb_graph_patterns = 1; + + stats = rte_graph_cluster_stats_create(&s_param); + if (stats == NULL) + rte_exit(EXIT_FAILURE, "Unable to create stats object\n"); + + /* Clear screen and move to top left */ + rte_graph_cluster_stats_get(stats, 0); + rte_delay_ms(1E3); + + fseek(fp, 0L, SEEK_END); + sz = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + len = strlen(conn->msg_out); + conn->msg_out += len; + + sz = fread(conn->msg_out, sizeof(char), sz, fp); + len = strlen(conn->msg_out); + conn->msg_out_len_max -= len; + rte_graph_cluster_stats_destroy(stats); + + fclose(fp); +} + +static void +cli_graph_stats(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + graph_stats_print_to_file(); +} + +static void +cli_graph_start(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct rte_node_ethdev_config *conf; + uint32_t nb_graphs = 0, nb_conf, i; + + conf = graph_rxtx_node_config_get(&nb_conf, &nb_graphs); + for (i = 0; i < MAX_GRAPH_USECASES; i++) { + if (!strcmp(graph_config.usecases[i].name, "l3fwd")) { + if (graph_config.usecases[i].enabled) { + RTE_SET_USED(conf); + break; + } + } + } +} + +static int +graph_config_add(char *usecases, struct graph_config *config) +{ + uint64_t lcore_id, core_num; + uint64_t eal_coremask = 0; + + if (!parser_usecases_read(usecases)) + return -EINVAL; + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if(rte_lcore_is_enabled(lcore_id)) + eal_coremask |= 1 << lcore_id; + } + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + core_num = 1 << lcore_id; + if (config->params.coremask & core_num) { + if (eal_coremask & core_num) { + continue; + } else { + return -EINVAL; + } + } + } + + graph_config.params.bsz = config->params.bsz; + graph_config.params.tmo = config->params.tmo; + graph_config.params.coremask = config->params.coremask; + graph_config.model = config->model; + graph_config.pcap_ena = config->pcap_ena; + graph_config.num_pcap_pkts = config->num_pcap_pkts; + graph_config.pcap_file = strdup(config->pcap_file); + + return 0; +} + +void +graph_pcap_config_get(uint8_t *pcap_ena, uint64_t *num_pkts, char **file) +{ + + *pcap_ena = graph_config.pcap_ena; + *num_pkts = graph_config.num_pcap_pkts; + *file = graph_config.pcap_file; +} + +int +graph_walk_start(void *conf) +{ + struct lcore_conf *qconf; + struct rte_graph *graph; + uint32_t lcore_id; + + RTE_SET_USED(conf); + + lcore_id = rte_lcore_id(); + qconf = &lcore_conf[lcore_id]; + graph = qconf->graph; + + if (!graph) { + RTE_LOG(INFO, APP_GRAPH, "Lcore %u has nothing to do\n", lcore_id); + return 0; + } + + RTE_LOG(INFO, APP_GRAPH, "Entering main loop on lcore %u, graph %s(%p)\n", lcore_id, + qconf->name, graph); + + while (likely(!force_quit)) + rte_graph_walk(graph); + + return 0; +} + +void +graph_stats_print(void) +{ + const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0'}; + const char clr[] = {27, '[', '2', 'J', '\0'}; + struct rte_graph_cluster_stats_param s_param; + struct rte_graph_cluster_stats *stats; + const char *pattern = "worker_*"; + + /* Prepare stats object */ + memset(&s_param, 0, sizeof(s_param)); + s_param.f = stdout; + s_param.socket_id = SOCKET_ID_ANY; + s_param.graph_patterns = &pattern; + s_param.nb_graph_patterns = 1; + + stats = rte_graph_cluster_stats_create(&s_param); + if (stats == NULL) + rte_exit(EXIT_FAILURE, "Unable to create stats object\n"); + + while (!force_quit) { + /* Clear screen and move to top left */ + printf("%s%s", clr, topLeft); + rte_graph_cluster_stats_get(stats, 0); + rte_delay_ms(1E3); + if (app_graph_exit()) + force_quit = true; + } + + rte_graph_cluster_stats_destroy(stats); +} + +uint64_t +graph_coremask_get(void) +{ + return graph_config.params.coremask; +} + +static void +cli_graph(void *parsed_result, __rte_unused struct cmdline *cl, __rte_unused void *data) +{ + struct graph_config_cmd_tokens *res = parsed_result; + struct graph_config config; + char *model_name; + uint8_t model; + int rc; + + model_name = res->model_name; + if (strcmp(model_name, "default") == 0) { + model = GRAPH_MODEL_RTC; + } else if (strcmp(model_name, "rtc") == 0) { + model = GRAPH_MODEL_RTC; + } else if (strcmp(model_name, "mcd") == 0) { + model = GRAPH_MODEL_MCD; + } else { + printf(MSG_ARG_NOT_FOUND, "model arguments"); + return; + } + + config.params.bsz = res->size; + config.params.tmo = res->ns; + config.params.coremask = res->mask; + config.model = model; + config.pcap_ena = res->pcap_ena; + config.num_pcap_pkts = res->num_pcap_pkts; + config.pcap_file = res->pcap_file; + rc = graph_config_add(res->usecase, &config); + if (rc < 0) { + cli_exit(); + printf(MSG_CMD_FAIL, res->graph); + rte_exit(EXIT_FAILURE, "coremask is Invalid\n"); + } +} + +static void +cli_graph_help(__rte_unused void *parsed_result, __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + size_t len; + + len = strlen(conn->msg_out); + conn->msg_out += len; + snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n%s\n", + "----------------------------- graph command help -----------------------------", + cmd_graph_help, "graph start"); + + len = strlen(conn->msg_out); + conn->msg_out_len_max -= len; +} + +cmdline_parse_token_string_t graph_display_graph = + TOKEN_STRING_INITIALIZER(struct graph_stats_cmd_tokens, graph, "graph"); +cmdline_parse_token_string_t graph_display_stats = + TOKEN_STRING_INITIALIZER(struct graph_stats_cmd_tokens, stats, "stats"); +cmdline_parse_token_string_t graph_display_show = + TOKEN_STRING_INITIALIZER(struct graph_stats_cmd_tokens, show, "show"); + +cmdline_parse_inst_t graph_stats_cmd_ctx = { + .f = cli_graph_stats, + .data = NULL, + .help_str = "graph stats show", + .tokens = { + (void *)&graph_display_graph, + (void *)&graph_display_stats, + (void *)&graph_display_show, + NULL, + }, +}; + +cmdline_parse_token_string_t graph_config_start_graph = + TOKEN_STRING_INITIALIZER(struct graph_start_cmd_tokens, graph, "graph"); +cmdline_parse_token_string_t graph_config_start = + TOKEN_STRING_INITIALIZER(struct graph_start_cmd_tokens, start, "start"); + +cmdline_parse_inst_t graph_start_cmd_ctx = { + .f = cli_graph_start, + .data = NULL, + .help_str = "graph start", + .tokens = { + (void *)&graph_config_start_graph, + (void *)&graph_config_start, + NULL, + }, +}; + +cmdline_parse_token_string_t graph_config_add_graph = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, graph, "graph"); +cmdline_parse_token_string_t graph_config_add_usecase = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, usecase, NULL); +cmdline_parse_token_string_t graph_config_add_coremask = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, coremask, "coremask"); +cmdline_parse_token_num_t graph_config_add_mask = + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, mask, RTE_UINT64); +cmdline_parse_token_string_t graph_config_add_bsz = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, bsz, "bsz"); +cmdline_parse_token_num_t graph_config_add_size = + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, size, RTE_UINT16); +cmdline_parse_token_string_t graph_config_add_tmo = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, tmo, "tmo"); +cmdline_parse_token_num_t graph_config_add_ns = + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, ns, RTE_UINT64); +cmdline_parse_token_string_t graph_config_add_model = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, model, "model"); +cmdline_parse_token_string_t graph_config_add_model_name = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, model_name, "rtc#mcd#default"); +cmdline_parse_token_string_t graph_config_add_capt_ena = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, capt_ena, "pcap_enable"); +cmdline_parse_token_num_t graph_config_add_pcap_ena = + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, pcap_ena, RTE_UINT8); +cmdline_parse_token_string_t graph_config_add_capt_pkts_count = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, capt_pkts_count, "num_pcap_pkts"); +cmdline_parse_token_num_t graph_config_add_num_pcap_pkts = + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, num_pcap_pkts, RTE_UINT64); +cmdline_parse_token_string_t graph_config_add_capt_file = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, capt_file, "pcap_file"); +cmdline_parse_token_string_t graph_config_add_pcap_file = + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, pcap_file, NULL); + +cmdline_parse_inst_t graph_config_cmd_ctx = { + .f = cli_graph, + .data = NULL, + .help_str = cmd_graph_help, + .tokens = { + (void *)&graph_config_add_graph, + (void *)&graph_config_add_usecase, + (void *)&graph_config_add_coremask, + (void *)&graph_config_add_mask, + (void *)&graph_config_add_bsz, + (void *)&graph_config_add_size, + (void *)&graph_config_add_tmo, + (void *)&graph_config_add_ns, + (void *)&graph_config_add_model, + (void *)&graph_config_add_model_name, + (void *)&graph_config_add_capt_ena, + (void *)&graph_config_add_pcap_ena, + (void *)&graph_config_add_capt_pkts_count, + (void *)&graph_config_add_num_pcap_pkts, + (void *)&graph_config_add_capt_file, + (void *)&graph_config_add_pcap_file, + NULL, + }, +}; + +cmdline_parse_token_string_t graph_help_cmd = + TOKEN_STRING_INITIALIZER(struct graph_help_cmd_tokens, help, "help"); +cmdline_parse_token_string_t graph_help_graph = + TOKEN_STRING_INITIALIZER(struct graph_help_cmd_tokens, graph, "graph"); + +cmdline_parse_inst_t graph_help_cmd_ctx = { + .f = cli_graph_help, + .data = NULL, + .help_str = "", + .tokens = { + (void *)&graph_help_cmd, + (void *)&graph_help_graph, + NULL, + }, +}; diff --git a/app/graph/graph.h b/app/graph/graph.h new file mode 100644 index 0000000000..1c3599ac8c --- /dev/null +++ b/app/graph/graph.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#ifndef APP_GRAPH_H +#define APP_GRAPH_H + +#include + +extern cmdline_parse_inst_t graph_config_cmd_ctx; +extern cmdline_parse_inst_t graph_start_cmd_ctx; +extern cmdline_parse_inst_t graph_stats_cmd_ctx; +extern cmdline_parse_inst_t graph_help_cmd_ctx; + +int graph_walk_start(void *conf); +void graph_stats_print(void); +void graph_pcap_config_get(uint8_t *pcap_ena, uint64_t *num_pkts, char **file); +uint64_t graph_coremask_get(void); + +#endif diff --git a/app/graph/graph_priv.h b/app/graph/graph_priv.h new file mode 100644 index 0000000000..a48a35daa3 --- /dev/null +++ b/app/graph/graph_priv.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#ifndef APP_GRAPH_PRIV_H +#define APP_GRAPH_PRIV_H + +#define MAX_GRAPH_USECASES 32 + +struct graph_help_cmd_tokens { + cmdline_fixed_string_t help; + cmdline_fixed_string_t graph; +}; + +struct graph_start_cmd_tokens { + cmdline_fixed_string_t graph; + cmdline_fixed_string_t start; +}; + +struct graph_stats_cmd_tokens { + cmdline_fixed_string_t show; + cmdline_fixed_string_t graph; + cmdline_fixed_string_t stats; +}; + +struct graph_config_cmd_tokens { + cmdline_fixed_string_t graph; + cmdline_fixed_string_t usecase; + cmdline_fixed_string_t bsz; + cmdline_fixed_string_t tmo; + cmdline_fixed_string_t coremask; + cmdline_fixed_string_t model; + cmdline_fixed_string_t capt_ena; + cmdline_fixed_string_t capt_pkts_count; + cmdline_fixed_string_t capt_file; + cmdline_fixed_string_t model_name; + cmdline_fixed_string_t pcap_file; + uint16_t size; + uint64_t ns; + uint64_t mask; + uint64_t num_pcap_pkts; + uint8_t pcap_ena; +}; + +enum graph_model { + GRAPH_MODEL_RTC = 0x01, + GRAPH_MODEL_MCD = 0x02, +}; + +struct usecases { + char name[32]; + bool enabled; +}; + +struct usecase_params { + uint64_t coremask; + uint32_t bsz; + uint32_t tmo; +}; + +struct graph_config { + struct usecases usecases[MAX_GRAPH_USECASES]; + struct usecase_params params; + enum graph_model model; + uint64_t num_pcap_pkts; + char *pcap_file; + uint8_t pcap_ena; +}; + +#endif diff --git a/app/graph/meson.build b/app/graph/meson.build index caf2d20735..6292fc9684 100644 --- a/app/graph/meson.build +++ b/app/graph/meson.build @@ -13,6 +13,7 @@ sources = files( 'conn.c', 'ethdev_rx.c', 'ethdev.c', + 'graph.c', 'ip4_route.c', 'ip6_route.c', 'main.c', diff --git a/app/graph/module_api.h b/app/graph/module_api.h index 0a4e383f50..8417c2d3dd 100644 --- a/app/graph/module_api.h +++ b/app/graph/module_api.h @@ -12,6 +12,7 @@ #include "conn.h" #include "ethdev.h" #include "ethdev_rx.h" +#include "graph.h" #include "mempool.h" #include "neigh.h" #include "route.h" diff --git a/doc/guides/tools/graph.rst b/doc/guides/tools/graph.rst index 56d8a08e5c..2c06f8e958 100644 --- a/doc/guides/tools/graph.rst +++ b/doc/guides/tools/graph.rst @@ -76,10 +76,25 @@ file to express the requested use case configuration. - Description - Dynamic - Optional - * - Dummy command - - Dummy command description + * - graph [bsz ] [tmo ] [coremask ] model + pcap_enable <0 | 1> num_pcap_pkts pcap_file + - Command to express the desired use case. Also enables/disable pcap capturing - No - No + * - graph start + - Command to start the graph. + This command triggers that no more commands are left to be parsed and graph + initialization can be started now. It must be the last command in ``.cli`` + - No + - No + * - graph stats show + - Command to dump current graph statistics + - Yes + - Yes + * - help graph + - Command to dump graph help message + - Yes + - Yes * - mempool size buffers cache numa - Command to create mempool which will be further associated to RxQ to dequeue the packets - No -- 2.25.1