[v4,1/1] app/testpmd: support congestion management CLIs

Message ID 20221202075647.2804081-1-skori@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series [v4,1/1] app/testpmd: support congestion management CLIs |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/github-robot: build success github build: passed
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS

Commit Message

Sunil Kumar Kori Dec. 2, 2022, 7:56 a.m. UTC
  From: Sunil Kumar Kori <skori@marvell.com>

Support congestion management CLIs.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
Acked-by: Aman Singh <aman.deep.singh@intel.com>
---
v3..v4:
 - Fix build error
v2..v3:
 - Move Congestion management document section near TM section
 - Rebase on top of the dpdk/main
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                 | 392 ++++++++++++++++++++
 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, 446 insertions(+)
 create mode 100644 app/test-pmd/cmdline_cman.c
 create mode 100644 app/test-pmd/cmdline_cman.h
  

Comments

Ferruh Yigit Dec. 7, 2022, 2:19 p.m. UTC | #1
On 12/2/2022 7:56 AM, skori@marvell.com wrote:
> From: Sunil Kumar Kori <skori@marvell.com>
> 
> Support congestion management CLIs.
> 
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
> Acked-by: Aman Singh <aman.deep.singh@intel.com>

Acked-by: Ferruh Yigit <ferruh.yigit@amd.com>

Applied to dpdk-next-net/main, thanks.
  

Patch

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b32dc8bfd4..cb8c174020 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -61,6 +61,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"
@@ -610,6 +611,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()
 		);
 	}
@@ -12851,6 +12863,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..1a34172f1f
--- /dev/null
+++ b/app/test-pmd/cmdline_cman.c
@@ -0,0 +1,392 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell International Ltd.
+ */
+
+#include <stdlib.h>
+
+#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 8488efc138..d2e3f60892 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 0037506a79..03663866ac 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2843,6 +2843,32 @@  where:
 * ``red`` enable 1, disable 0 marking IP ecn for yellow marked packets with ecn of 2'b01  or 2'b10
   to ecn of 2'b11 when IP is caring TCP or SCTP
 
+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
+
 Filter Functions
 ----------------