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

Reply via email to