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 AA895431DE; Mon, 23 Oct 2023 09:06:16 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9B6EA40A8B; Mon, 23 Oct 2023 09:06:16 +0200 (CEST) Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) by mails.dpdk.org (Postfix) with ESMTP id 9653840C35 for ; Mon, 23 Oct 2023 09:06:14 +0200 (CEST) Received: by mail-qt1-f174.google.com with SMTP id d75a77b69052e-41cbd1d7e04so18150181cf.1 for ; Mon, 23 Oct 2023 00:06:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1698044774; x=1698649574; darn=dpdk.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=+5ZG5kfQw3Q1McQ0gNcujGd9WXG7gjYKu1jXu/mqGSw=; b=a8jr5EdnKJ2gSYJhPbad/PrcqBFvIBXX2r2GvGaRjygIz3Lm2OJkrkC7PjoXPvntSJ VQp05svG1pySugpQQ+sad70VjYkrMwh4dRwHGsNCK3J8GqcLpthQM6+t+wWHuwtCWaQo 79R58X1pHiojvEvxWv/y586Y9bZ7WRNQBF5mM7jnQXNIBGt0vOkri+9stAa6MXD/ZJR6 CkzPn/9nigV4a4JTtXKD2u+g0CHWsvRXB3O3ukhB51imy5rTjD1fA+e80FxkRk57NL0a 5wwfPlsCWymDgaNoW5iTYy8Bti8f1bk+9PYNngP9J8yQrxxyWGOQ0BG8irkX21dSUivQ 41YA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698044774; x=1698649574; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+5ZG5kfQw3Q1McQ0gNcujGd9WXG7gjYKu1jXu/mqGSw=; b=rOrYuIQd4bJkDMnQRElT+ySaSbj0mAx2s/rf/5K2iHnv2o44U97Glbb0cJbkvNLGY/ 0sz3JtLyFevx7jfy5CZOyI532PuwUGgXNIVb/7vJK8Ln4ZspluAuD7OEO+1JxUZ6CUjU 5Aekmc3A4rS0wdlEZNofulwiWEXXNVPOoKBDH9yJykaEhWtwoZGjIk7T+i4N1H5POglI Re5FfxGXP6T9dxbQZoRe2ejCkHH3zj8fXt5pROQXuYLvBa7Ps3yBKFd/jMYMhPu5FeWl bakTTzvQAOLGW3cxTbFpT8EP5+70zvSG5281JAYn49LkyXDoYwhtVOVBDLiltB0xqIAW TwMg== X-Gm-Message-State: AOJu0YxxYTqNtyWhQZT4l+bHPmRa3L2qQzRbR5iJuwH3igMyRi+kGg0q A+6JcHR5lhXjCQ+80l/wFHDpvordRXUqOZ1tyCoHqcLnG4U= X-Google-Smtp-Source: AGHT+IHlIPdg4eIWl5lRotof4Zjd+tBEhAbBMzWk8J7Kne0AMUU7AWbQxJtAGyPftyCHSaicd1DNBBTW+u7FJ7VWWPA= X-Received: by 2002:a05:622a:174e:b0:419:52a9:9ffb with SMTP id l14-20020a05622a174e00b0041952a99ffbmr13144269qtk.20.1698044773812; Mon, 23 Oct 2023 00:06:13 -0700 (PDT) MIME-Version: 1.0 References: <20231019105000.520914-13-skori@marvell.com> <20231019173011.1186656-1-skori@marvell.com> <20231019173011.1186656-11-skori@marvell.com> In-Reply-To: <20231019173011.1186656-11-skori@marvell.com> From: Nithin Dabilpuram Date: Mon, 23 Oct 2023 12:36:01 +0530 Message-ID: Subject: Re: [PATCH v11 10/12] app/graph: support graph command line interfaces To: skori@marvell.com Cc: Rakesh Kudurumalla , dev@dpdk.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 Acked-By: Nithin Dabilpuram On Thu, Oct 19, 2023 at 11:12=E2=80=AFPM wrote: > > From: Rakesh Kudurumalla > > Adds graph module to create a graph for a given use case 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/ethdev_rx.c | 2 +- > app/graph/graph.c | 550 +++++++++++++++++++++++++++++++++++++ > app/graph/graph.h | 21 ++ > app/graph/graph_priv.h | 70 +++++ > app/graph/ip4_route.c | 5 +- > app/graph/ip6_route.c | 5 +- > app/graph/meson.build | 1 + > app/graph/module_api.h | 1 + > app/graph/neigh.c | 10 +- > doc/guides/tools/graph.rst | 19 ++ > 11 files changed, 683 insertions(+), 5 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 ad7d7deadf..30b12312d6 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[] =3D { > + (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/ethdev_rx.c b/app/graph/ethdev_rx.c > index f2cb8cf9a5..03f8effcca 100644 > --- a/app/graph/ethdev_rx.c > +++ b/app/graph/ethdev_rx.c > @@ -69,7 +69,7 @@ ethdev_rx_map_add(char *name, uint32_t queue, uint32_t = core) > if (rc) > return -EINVAL; > > - coremask =3D 0xff; /* FIXME: Read from graph configuration */ > + coremask =3D graph_coremask_get(); > > if (!(coremask & (1 << core))) > return -EINVAL; > diff --git a/app/graph/graph.c b/app/graph/graph.c > new file mode 100644 > index 0000000000..74a99dd68e > --- /dev/null > +++ b/app/graph/graph.c > @@ -0,0 +1,550 @@ > +/* 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[] =3D "graph bsz tmo coremask " > + "model pcap_enable <0 | 1> num_p= cap_pkts " > + "pcap_file "; > + > +static const char * const supported_usecases[] =3D {"l3fwd"}; > +struct graph_config graph_config; > +bool graph_started; > + > +/* 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 =3D 0; > + struct rte_eth_link link; > + uint16_t portid; > + int rc; > + > + printf("\nChecking link status..."); > + fflush(stdout); > + for (count =3D 0; count <=3D MAX_CHECK_TIME; count++) { > + if (force_quit) > + return; > + > + all_ports_up =3D 1; > + RTE_ETH_FOREACH_DEV(portid) > + { > + if (force_quit) > + return; > + > + if ((port_mask & (1 << portid)) =3D=3D 0) > + continue; > + > + memset(&link, 0, sizeof(link)); > + rc =3D rte_eth_link_get_nowait(portid, &link); > + if (rc < 0) { > + all_ports_up =3D 0; > + if (print_flag =3D=3D 1) > + printf("Port %u link get failed: = %s\n", > + portid, rte_strerror(-rc))= ; > + continue; > + } > + > + /* Print link rc if flag set */ > + if (print_flag =3D=3D 1) { > + rte_eth_link_to_str(link_rc_text, sizeof(= link_rc_text), > + &link); > + printf("Port %d %s\n", portid, link_rc_te= xt); > + continue; > + } > + > + /* Clear all_ports_up flag if any link down */ > + if (link.link_status =3D=3D RTE_ETH_LINK_DOWN) { > + all_ports_up =3D 0; > + break; > + } > + } > + > + /* After finally printing all link rc, get out */ > + if (print_flag =3D=3D 1) > + break; > + > + if (all_ports_up =3D=3D 0) { > + printf("."); > + fflush(stdout); > + rte_delay_ms(CHECK_INTERVAL); > + } > + > + /* Set the print_flag if all ports up or timeout */ > + if (all_ports_up =3D=3D 1 || count =3D=3D (MAX_CHECK_TIME= - 1)) { > + print_flag =3D 1; > + printf("Done\n"); > + } > + } > +} > + > +static bool > +parser_usecases_read(char *usecases) > +{ > + bool valid =3D false; > + uint32_t i, j =3D 0; > + char *token; > + > + token =3D strtok(usecases, ","); > + while (token !=3D NULL) { > + for (i =3D 0; i < RTE_DIM(supported_usecases); i++) { > + if (strcmp(supported_usecases[i], token) =3D=3D 0= ) { > + graph_config.usecases[j].enabled =3D true= ; > + rte_strscpy(graph_config.usecases[j].name= , token, 31); > + valid =3D true; > + j++; > + break; > + } > + } > + token =3D strtok(NULL, ","); > + } > + > + return valid; > +} > + > +static uint64_t > +graph_worker_count_get(void) > +{ > + uint64_t nb_worker =3D 0; > + uint64_t coremask; > + > + coremask =3D graph_config.params.coremask; > + while (coremask) { > + if (coremask & 0x1) > + nb_worker++; > + > + coremask =3D (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 =3D 0, lcore_id; > + uint16_t queueid, portid, nb_graphs =3D 0; > + uint8_t nb_rx_queue, queue; > + struct lcore_conf *qconf; > + > + n_tx_queue =3D graph_worker_count_get(); > + if (n_tx_queue > RTE_MAX_ETHPORTS) > + n_tx_queue =3D RTE_MAX_ETHPORTS; > + > + RTE_ETH_FOREACH_DEV(portid) { > + /* Skip ports that are not enabled */ > + if ((enabled_port_mask & (1 << portid)) =3D=3D 0) { > + printf("\nSkipping disabled port %d\n", portid); > + continue; > + } > + > + nb_rx_queue =3D ethdev_rx_num_rx_queues_get(portid); > + > + /* Setup ethdev node config */ > + ethdev_conf[nb_conf].port_id =3D portid; > + ethdev_conf[nb_conf].num_rx_queues =3D nb_rx_queue; > + ethdev_conf[nb_conf].num_tx_queues =3D n_tx_queue; > + ethdev_conf[nb_conf].mp =3D ethdev_mempool_list_by_portid= (portid); > + ethdev_conf[nb_conf].mp_count =3D 1; /* Check with pools = */ > + > + nb_conf++; > + } > + > + for (lcore_id =3D 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { > + if (rte_lcore_is_enabled(lcore_id) =3D=3D 0) > + continue; > + > + qconf =3D &lcore_conf[lcore_id]; > + printf("\nInitializing rx queues on lcore %u ... ", lcore= _id); > + fflush(stdout); > + > + /* Init RX queues */ > + for (queue =3D 0; queue < qconf->n_rx_queue; ++queue) { > + portid =3D qconf->rx_queue_list[queue].port_id; > + queueid =3D qconf->rx_queue_list[queue].queue_id; > + > + /* Add this queue node to its graph */ > + snprintf(qconf->rx_queue_list[queue].node_name, R= TE_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 =3D nb_conf; > + *num_graphs =3D 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 =3D "worker_*"; > + FILE *fp =3D NULL; > + size_t sz, len; > + > + /* Prepare stats object */ > + fp =3D fopen("/tmp/graph_stats.txt", "w+"); > + if (fp =3D=3D NULL) > + rte_exit(EXIT_FAILURE, "Error in opening stats file\n"); > + > + memset(&s_param, 0, sizeof(s_param)); > + s_param.f =3D fp; > + s_param.socket_id =3D SOCKET_ID_ANY; > + s_param.graph_patterns =3D &pattern; > + s_param.nb_graph_patterns =3D 1; > + > + stats =3D rte_graph_cluster_stats_create(&s_param); > + if (stats =3D=3D 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 =3D ftell(fp); > + fseek(fp, 0L, SEEK_SET); > + > + len =3D strlen(conn->msg_out); > + conn->msg_out +=3D len; > + > + sz =3D fread(conn->msg_out, sizeof(char), sz, fp); > + len =3D strlen(conn->msg_out); > + conn->msg_out_len_max -=3D len; > + rte_graph_cluster_stats_destroy(stats); > + > + fclose(fp); > +} > + > +static void > +cli_graph_stats(__rte_unused void *parsed_result, __rte_unused struct cm= dline *cl, > + __rte_unused void *data) > +{ > + graph_stats_print_to_file(); > +} > + > +bool > +graph_status_get(void) > +{ > + return graph_started; > +} > + > +static void > +cli_graph_start(__rte_unused void *parsed_result, __rte_unused struct cm= dline *cl, > + __rte_unused void *data) > +{ > + struct rte_node_ethdev_config *conf; > + uint32_t nb_graphs =3D 0, nb_conf, i; > + int rc =3D -EINVAL; > + > + conf =3D graph_rxtx_node_config_get(&nb_conf, &nb_graphs); > + for (i =3D 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; > + } > + } > + } > + > + if (!rc) > + graph_started =3D true; > +} > + > +static int > +graph_config_add(char *usecases, struct graph_config *config) > +{ > + uint64_t lcore_id, core_num; > + uint64_t eal_coremask =3D 0; > + > + if (!parser_usecases_read(usecases)) > + return -EINVAL; > + > + for (lcore_id =3D 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { > + if (rte_lcore_is_enabled(lcore_id)) > + eal_coremask |=3D RTE_BIT64(lcore_id); > + } > + > + for (lcore_id =3D 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { > + core_num =3D 1 << lcore_id; > + if (config->params.coremask & core_num) { > + if (eal_coremask & core_num) > + continue; > + else > + return -EINVAL; > + } > + } > + > + graph_config.params.bsz =3D config->params.bsz; > + graph_config.params.tmo =3D config->params.tmo; > + graph_config.params.coremask =3D config->params.coremask; > + graph_config.model =3D config->model; > + graph_config.pcap_ena =3D config->pcap_ena; > + graph_config.num_pcap_pkts =3D config->num_pcap_pkts; > + graph_config.pcap_file =3D strdup(config->pcap_file); > + > + return 0; > +} > + > +void > +graph_pcap_config_get(uint8_t *pcap_ena, uint64_t *num_pkts, char **file= ) > +{ > + > + *pcap_ena =3D graph_config.pcap_ena; > + *num_pkts =3D graph_config.num_pcap_pkts; > + *file =3D 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 =3D rte_lcore_id(); > + qconf =3D &lcore_conf[lcore_id]; > + graph =3D 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[] =3D {27, '[', '1', ';', '1', 'H', '\0'}; > + const char clr[] =3D {27, '[', '2', 'J', '\0'}; > + struct rte_graph_cluster_stats_param s_param; > + struct rte_graph_cluster_stats *stats; > + const char *pattern =3D "worker_*"; > + > + /* Prepare stats object */ > + memset(&s_param, 0, sizeof(s_param)); > + s_param.f =3D stdout; > + s_param.socket_id =3D SOCKET_ID_ANY; > + s_param.graph_patterns =3D &pattern; > + s_param.nb_graph_patterns =3D 1; > + > + stats =3D rte_graph_cluster_stats_create(&s_param); > + if (stats =3D=3D 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 =3D 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_un= used void *data) > +{ > + struct graph_config_cmd_tokens *res =3D parsed_result; > + struct graph_config config; > + char *model_name; > + uint8_t model; > + int rc; > + > + model_name =3D res->model_name; > + if (strcmp(model_name, "default") =3D=3D 0) { > + model =3D GRAPH_MODEL_RTC; > + } else if (strcmp(model_name, "rtc") =3D=3D 0) { > + model =3D GRAPH_MODEL_RTC; > + } else if (strcmp(model_name, "mcd") =3D=3D 0) { > + model =3D GRAPH_MODEL_MCD; > + } else { > + printf(MSG_ARG_NOT_FOUND, "model arguments"); > + return; > + } > + > + config.params.bsz =3D res->size; > + config.params.tmo =3D res->ns; > + config.params.coremask =3D res->mask; > + config.model =3D model; > + config.pcap_ena =3D res->pcap_ena; > + config.num_pcap_pkts =3D res->num_pcap_pkts; > + config.pcap_file =3D res->pcap_file; > + rc =3D 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 cmd= line *cl, > + __rte_unused void *data) > +{ > + size_t len; > + > + len =3D strlen(conn->msg_out); > + conn->msg_out +=3D len; > + snprintf(conn->msg_out, conn->msg_out_len_max, "\n%s\n%s\n%s\n%s\= n", > + "----------------------------- graph command help ------= -----------------------", > + cmd_graph_help, "graph start", "graph stats show"); > + > + len =3D strlen(conn->msg_out); > + conn->msg_out_len_max -=3D len; > +} > + > +cmdline_parse_token_string_t graph_display_graph =3D > + TOKEN_STRING_INITIALIZER(struct graph_stats_cmd_tokens, graph, "g= raph"); > +cmdline_parse_token_string_t graph_display_stats =3D > + TOKEN_STRING_INITIALIZER(struct graph_stats_cmd_tokens, stats, "s= tats"); > +cmdline_parse_token_string_t graph_display_show =3D > + TOKEN_STRING_INITIALIZER(struct graph_stats_cmd_tokens, show, "sh= ow"); > + > +cmdline_parse_inst_t graph_stats_cmd_ctx =3D { > + .f =3D cli_graph_stats, > + .data =3D NULL, > + .help_str =3D "graph stats show", > + .tokens =3D { > + (void *)&graph_display_graph, > + (void *)&graph_display_stats, > + (void *)&graph_display_show, > + NULL, > + }, > +}; > + > +cmdline_parse_token_string_t graph_config_start_graph =3D > + TOKEN_STRING_INITIALIZER(struct graph_start_cmd_tokens, graph, "g= raph"); > +cmdline_parse_token_string_t graph_config_start =3D > + TOKEN_STRING_INITIALIZER(struct graph_start_cmd_tokens, start, "s= tart"); > + > +cmdline_parse_inst_t graph_start_cmd_ctx =3D { > + .f =3D cli_graph_start, > + .data =3D NULL, > + .help_str =3D "graph start", > + .tokens =3D { > + (void *)&graph_config_start_graph, > + (void *)&graph_config_start, > + NULL, > + }, > +}; > + > +cmdline_parse_token_string_t graph_config_add_graph =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, graph, "= graph"); > +cmdline_parse_token_string_t graph_config_add_usecase =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, usecase,= NULL); > +cmdline_parse_token_string_t graph_config_add_coremask =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, coremask= , "coremask"); > +cmdline_parse_token_num_t graph_config_add_mask =3D > + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, mask, RTE_U= INT64); > +cmdline_parse_token_string_t graph_config_add_bsz =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, bsz, "bs= z"); > +cmdline_parse_token_num_t graph_config_add_size =3D > + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, size, RTE_U= INT16); > +cmdline_parse_token_string_t graph_config_add_tmo =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, tmo, "tm= o"); > +cmdline_parse_token_num_t graph_config_add_ns =3D > + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, ns, RTE_UIN= T64); > +cmdline_parse_token_string_t graph_config_add_model =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, model, "= model"); > +cmdline_parse_token_string_t graph_config_add_model_name =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, model_na= me, "rtc#mcd#default"); > +cmdline_parse_token_string_t graph_config_add_capt_ena =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, capt_ena= , "pcap_enable"); > +cmdline_parse_token_num_t graph_config_add_pcap_ena =3D > + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, pcap_ena, R= TE_UINT8); > +cmdline_parse_token_string_t graph_config_add_capt_pkts_count =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, capt_pkt= s_count, "num_pcap_pkts"); > +cmdline_parse_token_num_t graph_config_add_num_pcap_pkts =3D > + TOKEN_NUM_INITIALIZER(struct graph_config_cmd_tokens, num_pcap_pk= ts, RTE_UINT64); > +cmdline_parse_token_string_t graph_config_add_capt_file =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, capt_fil= e, "pcap_file"); > +cmdline_parse_token_string_t graph_config_add_pcap_file =3D > + TOKEN_STRING_INITIALIZER(struct graph_config_cmd_tokens, pcap_fil= e, NULL); > + > +cmdline_parse_inst_t graph_config_cmd_ctx =3D { > + .f =3D cli_graph, > + .data =3D NULL, > + .help_str =3D cmd_graph_help, > + .tokens =3D { > + (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 =3D > + TOKEN_STRING_INITIALIZER(struct graph_help_cmd_tokens, help, "hel= p"); > +cmdline_parse_token_string_t graph_help_graph =3D > + TOKEN_STRING_INITIALIZER(struct graph_help_cmd_tokens, graph, "gr= aph"); > + > +cmdline_parse_inst_t graph_help_cmd_ctx =3D { > + .f =3D cli_graph_help, > + .data =3D NULL, > + .help_str =3D "", > + .tokens =3D { > + (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..a14fa37ccd > --- /dev/null > +++ b/app/graph/graph.h > @@ -0,0 +1,21 @@ > +/* 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); > +bool graph_status_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 =3D 0x01, > + GRAPH_MODEL_MCD =3D 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/ip4_route.c b/app/graph/ip4_route.c > index db3354c270..fc83586427 100644 > --- a/app/graph/ip4_route.c > +++ b/app/graph/ip4_route.c > @@ -97,11 +97,14 @@ route_ip4_add(struct route_ipv4_config *route) > ipv4route->via =3D route->via; > ipv4route->is_used =3D true; > > - /* FIXME: Get graph status here and then update table */ > + if (!graph_status_get()) > + goto exit; > + > rc =3D route4_rewirte_table_update(ipv4route); > if (rc) > goto free; > > +exit: > TAILQ_INSERT_TAIL(&route4, ipv4route, next); > return 0; > free: > diff --git a/app/graph/ip6_route.c b/app/graph/ip6_route.c > index e793cde830..1fa4865220 100644 > --- a/app/graph/ip6_route.c > +++ b/app/graph/ip6_route.c > @@ -102,11 +102,14 @@ route_ip6_add(struct route_ipv6_config *route) > } > ipv6route->is_used =3D true; > > - /* FIXME: Get graph status here and then update table */ > + if (!graph_status_get()) > + goto exit; > + > rc =3D route6_rewirte_table_update(ipv6route); > if (rc) > goto free; > > +exit: > TAILQ_INSERT_TAIL(&route6, ipv6route, next); > return 0; > free: > diff --git a/app/graph/meson.build b/app/graph/meson.build > index d8391d5cae..15d16a302e 100644 > --- a/app/graph/meson.build > +++ b/app/graph/meson.build > @@ -14,6 +14,7 @@ sources =3D 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 56b7c94ecc..392dcfb222 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/app/graph/neigh.c b/app/graph/neigh.c > index 0cee502719..22be7361e3 100644 > --- a/app/graph/neigh.c > +++ b/app/graph/neigh.c > @@ -154,11 +154,14 @@ neigh_ip4_add(uint32_t ip, uint64_t mac) > v4_config->mac =3D mac; > v4_config->is_used =3D true; > > - /* FIXME: Get graph status here and then update table */ > + if (!graph_status_get()) > + goto exit; > + > rc =3D ip4_rewrite_node_add(v4_config); > if (rc) > goto free; > > +exit: > TAILQ_INSERT_TAIL(&neigh4, v4_config, next); > return 0; > free: > @@ -187,11 +190,14 @@ neigh_ip6_add(uint8_t *ip, uint64_t mac) > v6_config->mac =3D mac; > v6_config->is_used =3D true; > > - /* FIXME: Get graph status here and then update table */ > + if (!graph_status_get()) > + goto exit; > + > rc =3D ip6_rewrite_node_add(v6_config); > if (rc) > goto free; > > +exit: > TAILQ_INSERT_TAIL(&neigh6, v6_config, next); > return 0; > free: > diff --git a/doc/guides/tools/graph.rst b/doc/guides/tools/graph.rst > index 318d92a0fb..08ec57b7f8 100644 > --- a/doc/guides/tools/graph.rst > +++ b/doc/guides/tools/graph.rst > @@ -71,6 +71,25 @@ file to express the requested use case configuration. > +--------------------------------------+-----------------------------= ------+---------+----------+ > | Command | Description = | Dynamic | Optional | > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+ > + | | graph [bsz ] | | Command to express the des= ired | No | No | > + | | [tmo ] [coremask ] | | use case. Also enables/dis= able | | | > + | | model pcap_enable| | pcap capturing. = | | | > + | | <0/1> num_pcap_pkts pcap_file| = | | | > + | | | = | | | > + +--------------------------------------+-----------------------------= ------+---------+----------+ > + | graph start | | Command to start the graph= . | No | No | > + | | | This command triggers that= no | | | > + | | | more commands are left to = be | | | > + | | | parsed and graph initializ= ation | | | > + | | | can be started now. It mus= t be | | | > + | | | the last command in usecas= e.cli | | | > + +--------------------------------------+-----------------------------= ------+---------+----------+ > + | graph stats show | | Command to dump current gr= aph | Yes | Yes | > + | | | statistics. = | | | > + +--------------------------------------+-----------------------------= ------+---------+----------+ > + | help graph | | Command to dump graph help= | Yes | Yes | > + | | | message. = | | | > + +--------------------------------------+-----------------------------= ------+---------+----------+ > | | mempool size | | Command to create mempool = which | No | No | > | | buffers | | will be further associated= to | | | > | | | | RxQ to dequeue the packets= . | | | > -- > 2.25.1 >