Please review the following changes and provide feedback. Regards Sunil Kumar Kori
> -----Original Message----- > From: sk...@marvell.com <sk...@marvell.com> > Sent: Thursday, September 29, 2022 3:25 PM > To: Aman Singh <aman.deep.si...@intel.com>; Yuying Zhang > <yuying.zh...@intel.com> > Cc: dev@dpdk.org; Sunil Kumar Kori <sk...@marvell.com> > Subject: [PATCH v2 1/3] app/testpmd: support congestion management CLIs > > From: Sunil Kumar Kori <sk...@marvell.com> > > Support congestion management CLIs. > > Depends-on: patch-24902 ("ethdev: support congestion management") > > Signed-off-by: Sunil Kumar Kori <sk...@marvell.com> > --- > v1..v2: > - Rebase on top of the dpdk-next-net-mrvl/for-next-net > > app/test-pmd/cmdline.c | 15 + > app/test-pmd/cmdline_cman.c | 390 ++++++++++++++++++++ > app/test-pmd/cmdline_cman.h | 12 + > app/test-pmd/meson.build | 1 + > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 26 ++ > 5 files changed, 444 insertions(+) > create mode 100644 app/test-pmd/cmdline_cman.c create mode 100644 > app/test-pmd/cmdline_cman.h > > diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index > 51321de9ed..ce278eadb0 100644 > --- a/app/test-pmd/cmdline.c > +++ b/app/test-pmd/cmdline.c > @@ -60,6 +60,7 @@ > #include <rte_pmd_bnxt.h> > #endif > #include "testpmd.h" > +#include "cmdline_cman.h" > #include "cmdline_mtr.h" > #include "cmdline_tm.h" > #include "bpf_cmd.h" > @@ -599,6 +600,17 @@ static void cmd_help_long_parsed(void > *parsed_result, > "set port (port_id) fec_mode auto|off|rs|baser\n" > " set fec mode for a specific port\n\n" > > + "show port cman capa (port_id)\n" > + " Show congestion management capabilities\n\n" > + > + "show port cman config (port_id)\n" > + " Show congestion management configuration\n\n" > + > + "set port cman config (port_id) (queue_id) default | " > + "[obj (queue|queue_mempool) mode red > (min_thresh) " > + "(max_thresh) (prob_inv)]\n" > + " Set congestion management configuration\n\n" > + > , list_pkt_forwarding_modes() > ); > } > @@ -12990,6 +13002,9 @@ static cmdline_parse_ctx_t builtin_ctx[] = { > (cmdline_parse_inst_t *)&cmd_show_capability, > (cmdline_parse_inst_t *)&cmd_set_flex_is_pattern, > (cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern, > + (cmdline_parse_inst_t *)&cmd_show_port_cman_capa, > + (cmdline_parse_inst_t *)&cmd_show_port_cman_config, > + (cmdline_parse_inst_t *)&cmd_set_port_cman_config, > NULL, > }; > > diff --git a/app/test-pmd/cmdline_cman.c b/app/test-pmd/cmdline_cman.c > new file mode 100644 index 0000000000..344759189d > --- /dev/null > +++ b/app/test-pmd/cmdline_cman.c > @@ -0,0 +1,390 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2022 Marvell International Ltd. > + */ > + > +#include <cmdline_parse.h> > +#include <cmdline_parse_num.h> > +#include <cmdline_parse_string.h> > + > +#include <rte_ethdev.h> > + > +#include "testpmd.h" > + > +#define PARSE_DELIMITER " \f\n\r\t\v" > + > +static int > +parse_uint(uint64_t *value, const char *str) { > + char *next = NULL; > + uint64_t n; > + > + errno = 0; > + /* Parse number string */ > + n = strtol(str, &next, 10); > + if (errno != 0 || str == next || *next != '\0') > + return -1; > + > + *value = n; > + > + return 0; > +} > + > +static int > +parse_cman_obj_str(char *str, uint64_t *obj) { > + char *token; > + > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) > + return 0; > + > + if (strcasecmp(token, "queue") == 0) > + *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE; > + else if (strcasecmp(token, "queue_mempool") == 0) > + *obj = RTE_ETH_CMAN_OBJ_RX_QUEUE_MEMPOOL; > + else > + return -1; > + > + return 0; > +} > + > +static int > +parse_cman_mode_str(char *str, uint64_t *mode) { > + char *token; > + > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) > + return 0; > + > + if (strcasecmp(token, "red") == 0) > + *mode = RTE_CMAN_RED; > + else > + return -1; > + > + return 0; > +} > + > +static int > +parse_cman_params_str(uint16_t port_id, char *str, > + struct rte_eth_cman_config *cfg) { > + uint64_t obj = 0, mode = 0, min_th = 0, max_th = 0, maxp_inv = 0; > + struct rte_eth_cman_info info; > + char *token; > + int ret; > + > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (!strcasecmp(token, "default")) { > + ret = rte_eth_cman_config_init(port_id, cfg); > + if (ret) { > + fprintf(stderr, "error in default initialization\n"); > + return ret; > + } > + return 0; > + } > + > + /* First token: obj name */ > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) { > + fprintf(stderr, "Object param parse error\n"); > + goto error; > + } > + > + ret = parse_cman_obj_str(token, &obj); > + if (ret) { > + fprintf(stderr, "Object value is invalid\n"); > + goto error; > + } > + > + /* Second token: mode name */ > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) { > + fprintf(stderr, " Mode param is invalid\n"); > + goto error; > + } > + > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) { > + fprintf(stderr, " Mode value is invalid\n"); > + goto error; > + } > + > + ret = parse_cman_mode_str(token, &mode); > + if (ret) { > + fprintf(stderr, "mode string parse error\n"); > + goto error; > + } > + > + /* Third token: minimum threshold */ > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) { > + fprintf(stderr, "Minimum threshold parse error\n"); > + goto error; > + } > + > + ret = parse_uint(&min_th, token); > + if (ret != 0 || min_th > UINT8_MAX) { > + fprintf(stderr, "Minimum threshold is invalid\n"); > + goto error; > + } > + > + /* Fourth token: maximum threshold */ > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) { > + fprintf(stderr, "Maximum threshold parse error\n"); > + goto error; > + } > + > + ret = parse_uint(&max_th, token); > + if (ret != 0 || max_th > UINT8_MAX) { > + fprintf(stderr, "Maximum threshold is invalid\n"); > + goto error; > + } > + > + /* Fifth token: probability inversion */ > + token = strtok_r(str, PARSE_DELIMITER, &str); > + if (token == NULL) { > + fprintf(stderr, "Maximum probability inversion parse > error\n"); > + goto error; > + } > + > + ret = parse_uint(&maxp_inv, token); > + if (ret != 0 || maxp_inv == 0 || maxp_inv > UINT16_MAX) { > + fprintf(stderr, "Maximum probability inversion is invalid\n"); > + goto error; > + } > + > + memset(&info, 0, sizeof(struct rte_eth_cman_info)); > + ret = rte_eth_cman_info_get(port_id, &info); > + if (ret) { > + fprintf(stderr, "Congestion management capa get error\n"); > + goto error; > + } > + > + if (!(info.objs_supported & obj)) { > + fprintf(stderr, "Object type is not supported by driver\n"); > + goto error; > + } > + > + if (!(info.modes_supported & mode)) { > + fprintf(stderr, "Mode is not supported by driver\n"); > + goto error; > + } > + > + cfg->obj = obj; > + cfg->mode = mode; > + cfg->mode_param.red.min_th = min_th; > + cfg->mode_param.red.max_th = max_th; > + cfg->mode_param.red.maxp_inv = maxp_inv; > + > + return 0; > + > +error: > + return -EINVAL; > +} > + > +/* *** Show Port Congestion Management Capabilities *** */ struct > +cmd_show_port_cman_capa_result { > + cmdline_fixed_string_t show; > + cmdline_fixed_string_t port; > + cmdline_fixed_string_t cman; > + cmdline_fixed_string_t capa; > + uint16_t port_id; > +}; > + > +static cmdline_parse_token_string_t cmd_show_port_cman_capa_show = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_capa_result, show, "show"); > + > +static cmdline_parse_token_string_t cmd_show_port_cman_capa_port = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_capa_result, port, "port"); > + > +static cmdline_parse_token_string_t cmd_show_port_cman_capa_cman = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_capa_result, cman, "cman"); > + > +static cmdline_parse_token_string_t cmd_show_port_cman_capa_capa = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_capa_result, capa, "capa"); > + > +static cmdline_parse_token_num_t cmd_show_port_cman_capa_port_id = > + TOKEN_NUM_INITIALIZER( > + struct cmd_show_port_cman_capa_result, port_id, > RTE_UINT16); > + > +static void cmd_show_port_cman_capa_parsed(void *parsed_result, > + __rte_unused struct cmdline *cl, > + __rte_unused void *data) > +{ > + struct cmd_show_port_cman_capa_result *res = parsed_result; > + uint16_t port_id = res->port_id; > + struct rte_eth_cman_info info; > + int ret; > + > + memset(&info, 0, sizeof(struct rte_eth_cman_info)); > + ret = rte_eth_cman_info_get(port_id, &info); > + if (ret) > + return; > + > + printf("\n**** Port Congestion Management Capabilities > ****\n\n"); > + printf("modes_supported 0x%" PRIx64 "\n", info.modes_supported); > + printf("objs_supported 0x%" PRIx64 "\n", info.objs_supported); } > + > +cmdline_parse_inst_t cmd_show_port_cman_capa = { > + .f = cmd_show_port_cman_capa_parsed, > + .data = NULL, > + .help_str = "show port cman capa <port_id>", > + .tokens = { > + (void *)&cmd_show_port_cman_capa_show, > + (void *)&cmd_show_port_cman_capa_port, > + (void *)&cmd_show_port_cman_capa_cman, > + (void *)&cmd_show_port_cman_capa_capa, > + (void *)&cmd_show_port_cman_capa_port_id, > + NULL, > + }, > +}; > + > +/* *** Show Port Congestion Management configuration *** */ struct > +cmd_show_port_cman_cfg_result { > + cmdline_fixed_string_t show; > + cmdline_fixed_string_t port; > + cmdline_fixed_string_t cman; > + cmdline_fixed_string_t cfg; > + uint16_t port_id; > +}; > + > +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_show = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_cfg_result, show, "show"); > + > +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_port = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_cfg_result, port, "port"); > + > +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cman = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_cfg_result, cman, "cman"); > + > +static cmdline_parse_token_string_t cmd_show_port_cman_cfg_cfg = > + TOKEN_STRING_INITIALIZER( > + struct cmd_show_port_cman_cfg_result, cfg, "config"); > + > +static cmdline_parse_token_num_t cmd_show_port_cman_cfg_port_id = > + TOKEN_NUM_INITIALIZER( > + struct cmd_show_port_cman_cfg_result, port_id, > RTE_UINT16); > + > +static void cmd_show_port_cman_cfg_parsed(void *parsed_result, > + __rte_unused struct cmdline *cl, > + __rte_unused void *data) > +{ > + struct cmd_show_port_cman_cfg_result *res = parsed_result; > + uint16_t port_id = res->port_id; > + struct rte_eth_cman_config cfg; > + int ret; > + > + memset(&cfg, 0, sizeof(struct rte_eth_cman_config)); > + ret = rte_eth_cman_config_get(port_id, &cfg); > + if (ret) > + return; > + > + printf("\n**** Port Congestion Management Configuration > ****\n\n"); > + printf("cman object 0x%" PRIx32 "\n", cfg.obj); > + printf("cman Rx queue %" PRIx16 "\n", cfg.obj_param.rx_queue); > + printf("cman mode 0x%" PRIx32 "\n", cfg.mode); > + printf("cman RED min thresh %" PRIx8 "\n", > cfg.mode_param.red.min_th); > + printf("cman RED max thresh %" PRIx8 "\n", > cfg.mode_param.red.max_th); > + printf("cman RED Prob inversion %" PRIx16 "\n", > + cfg.mode_param.red.maxp_inv); > +} > + > +cmdline_parse_inst_t cmd_show_port_cman_config = { > + .f = cmd_show_port_cman_cfg_parsed, > + .data = NULL, > + .help_str = "show port cman config <port_id>", > + .tokens = { > + (void *)&cmd_show_port_cman_cfg_show, > + (void *)&cmd_show_port_cman_cfg_port, > + (void *)&cmd_show_port_cman_cfg_cman, > + (void *)&cmd_show_port_cman_cfg_cfg, > + (void *)&cmd_show_port_cman_cfg_port_id, > + NULL, > + }, > +}; > + > +/* *** Set Port Congestion Management configuration *** */ struct > +cmd_set_port_cman_cfg_result { > + cmdline_fixed_string_t set; > + cmdline_fixed_string_t port; > + cmdline_fixed_string_t cman; > + cmdline_fixed_string_t cfg; > + uint16_t port_id; > + uint16_t qid; > + cmdline_multi_string_t params; > +}; > + > +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_set = > + TOKEN_STRING_INITIALIZER( > + struct cmd_set_port_cman_cfg_result, set, "set"); > + > +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_port = > + TOKEN_STRING_INITIALIZER( > + struct cmd_set_port_cman_cfg_result, port, "port"); > + > +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cman = > + TOKEN_STRING_INITIALIZER( > + struct cmd_set_port_cman_cfg_result, cman, "cman"); > + > +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_cfg = > + TOKEN_STRING_INITIALIZER( > + struct cmd_set_port_cman_cfg_result, cfg, "config"); > + > +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_port_id = > + TOKEN_NUM_INITIALIZER( > + struct cmd_set_port_cman_cfg_result, port_id, RTE_UINT16); > + > +static cmdline_parse_token_num_t cmd_set_port_cman_cfg_qid = > + TOKEN_NUM_INITIALIZER( > + struct cmd_set_port_cman_cfg_result, qid, RTE_UINT16); > + > +static cmdline_parse_token_string_t cmd_set_port_cman_cfg_params = > + TOKEN_STRING_INITIALIZER(struct cmd_set_port_cman_cfg_result, > + params, TOKEN_STRING_MULTI); > + > +static void cmd_set_port_cman_cfg_parsed(void *parsed_result, > + __rte_unused struct cmdline *cl, > + __rte_unused void *data) > +{ > + struct cmd_set_port_cman_cfg_result *res = parsed_result; > + uint16_t port_id = res->port_id; > + struct rte_eth_cman_config cfg; > + int ret; > + > + ret = parse_cman_params_str(port_id, res->params, &cfg); > + if (ret) { > + fprintf(stderr, "params string parse error\n"); > + return; > + } > + > + cfg.obj_param.rx_queue = res->qid; > + rte_eth_cman_config_set(port_id, &cfg); } > + > +cmdline_parse_inst_t cmd_set_port_cman_config = { > + .f = cmd_set_port_cman_cfg_parsed, > + .data = NULL, > + .help_str = "set port cman config <port_id> <queue_id> " > + "default | [obj <queue|queue_mempool> mode red " > + "<min_thresh> <max_thresh> <prob_inv>]", > + .tokens = { > + (void *)&cmd_set_port_cman_cfg_set, > + (void *)&cmd_set_port_cman_cfg_port, > + (void *)&cmd_set_port_cman_cfg_cman, > + (void *)&cmd_set_port_cman_cfg_cfg, > + (void *)&cmd_set_port_cman_cfg_port_id, > + (void *)&cmd_set_port_cman_cfg_qid, > + (void *)&cmd_set_port_cman_cfg_params, > + NULL, > + }, > +}; > diff --git a/app/test-pmd/cmdline_cman.h b/app/test-pmd/cmdline_cman.h > new file mode 100644 index 0000000000..bd6c99ce35 > --- /dev/null > +++ b/app/test-pmd/cmdline_cman.h > @@ -0,0 +1,12 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2022 Marvell International Ltd. > + */ > + > +#ifndef _CMDLINE_CMAN_H_ > +#define _CMDLINE_CMAN_H_ > + > +extern cmdline_parse_inst_t cmd_show_port_cman_capa; extern > +cmdline_parse_inst_t cmd_show_port_cman_config; extern > +cmdline_parse_inst_t cmd_set_port_cman_config; > + > +#endif /* _CMDLINE_CMAN_H_ */ > diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index > 74399178dd..c03d9dfebb 100644 > --- a/app/test-pmd/meson.build > +++ b/app/test-pmd/meson.build > @@ -7,6 +7,7 @@ cflags += '-Wno-deprecated-declarations' > sources = files( > '5tswap.c', > 'cmdline.c', > + 'cmdline_cman.c', > 'cmdline_flow.c', > 'cmdline_mtr.c', > 'cmdline_tm.c', > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > index d3075bf87d..b9c7b468af 100644 > --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > @@ -5317,6 +5317,32 @@ Flex pattern can be shared between ports. > testpmd> flow create 0 ingress pattern eth / ipv4 / udp / flex item is 3 > pattern is 2 / end actions mark id 1 / queue index 0 / end > Flow rule #0 created > > +Congestion Management > +--------------------- > + > +Get capabilities > +~~~~~~~~~~~~~~~~ > + > +Retrieve congestion management capabilities supported by driver for given > port. > +Below example command retrieves capabilities for port 0:: > + > + testpmd> show port cman capa 0 > + > +Get configuration > +~~~~~~~~~~~~~~~~~ > +Retrieve congestion management configuration for given port. Below > +example command retrieves configuration for port 0:: > + > + testpmd> show port cman config 0 > + > +Set configuration > +~~~~~~~~~~~~~~~~~ > +Configures congestion management settings on given queue or mempool > +associated with queue. Below example command configures RED as > +congestion management algo for port 0 and queue 0:: > + > + testpmd> set port cman config 0 0 obj queue mode red 10 100 1 > + > Driver specific commands > ------------------------ > > -- > 2.25.1