From: Rakesh Kudurumalla <rkuduruma...@marvell.com> Adds ethdev_rx module to create port-queue-core mapping.
Mapping will be used to launch graph worker thread and dequeue packets on mentioned core from desired port/queue. Following commands are exposed: - ethdev_rx map port <ethdev_name> queue <q_num> core <core_id> - help ethdev_rx Signed-off-by: Sunil Kumar Kori <sk...@marvell.com> Signed-off-by: Rakesh Kudurumalla <rkuduruma...@marvell.com> --- app/graph/cli.c | 2 + app/graph/ethdev_rx.c | 165 +++++++++++++++++++++++++++++++++++++ app/graph/ethdev_rx.h | 37 +++++++++ app/graph/ethdev_rx_priv.h | 39 +++++++++ app/graph/meson.build | 1 + app/graph/module_api.h | 1 + doc/guides/tools/graph.rst | 10 +++ 7 files changed, 255 insertions(+) create mode 100644 app/graph/ethdev_rx.c create mode 100644 app/graph/ethdev_rx.h create mode 100644 app/graph/ethdev_rx_priv.h diff --git a/app/graph/cli.c b/app/graph/cli.c index f564362da1..ad7d7deadf 100644 --- a/app/graph/cli.c +++ b/app/graph/cli.c @@ -30,6 +30,8 @@ cmdline_parse_ctx_t modules_ctx[] = { (cmdline_parse_inst_t *)ðdev_ip6_cmd_ctx, (cmdline_parse_inst_t *)ðdev_cmd_ctx, (cmdline_parse_inst_t *)ðdev_help_cmd_ctx, + (cmdline_parse_inst_t *)ðdev_rx_cmd_ctx, + (cmdline_parse_inst_t *)ðdev_rx_help_cmd_ctx, (cmdline_parse_inst_t *)&ipv4_lookup_cmd_ctx, (cmdline_parse_inst_t *)&ipv4_lookup_help_cmd_ctx, (cmdline_parse_inst_t *)&ipv6_lookup_cmd_ctx, diff --git a/app/graph/ethdev_rx.c b/app/graph/ethdev_rx.c new file mode 100644 index 0000000000..f2cb8cf9a5 --- /dev/null +++ b/app/graph/ethdev_rx.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#include <stdlib.h> +#include <string.h> + +#include <cmdline_parse.h> +#include <cmdline_parse_num.h> +#include <cmdline_parse_string.h> +#include <cmdline_socket.h> +#include <rte_ethdev.h> + +#include "ethdev_rx_priv.h" +#include "module_api.h" + +static const char +cmd_ethdev_rx_help[] = "ethdev_rx map port <ethdev_name> queue <q_num> core <core_id>"; + +static struct lcore_params lcore_params_array[ETHDEV_RX_LCORE_PARAMS_MAX]; +struct rte_node_ethdev_config ethdev_conf[RTE_MAX_ETHPORTS]; +struct lcore_params *lcore_params = lcore_params_array; +struct lcore_conf lcore_conf[RTE_MAX_LCORE]; +uint16_t nb_lcore_params; + +static void +rx_map_configure(uint8_t port_id, uint32_t queue, uint32_t core) +{ + uint8_t n_rx_queue; + + n_rx_queue = lcore_conf[core].n_rx_queue; + lcore_conf[core].rx_queue_list[n_rx_queue].port_id = port_id; + lcore_conf[core].rx_queue_list[n_rx_queue].queue_id = queue; + lcore_conf[core].n_rx_queue++; +} + +uint8_t +ethdev_rx_num_rx_queues_get(uint16_t port) +{ + int queue = -1; + uint16_t i; + + for (i = 0; i < nb_lcore_params; ++i) { + if (lcore_params[i].port_id == port) { + if (lcore_params[i].queue_id == queue + 1) + queue = lcore_params[i].queue_id; + else + rte_exit(EXIT_FAILURE, + "Queue ids of the port %d must be" + " in sequence and must start with 0\n", + lcore_params[i].port_id); + } + } + + return (uint8_t)(++queue); +} + +static int +ethdev_rx_map_add(char *name, uint32_t queue, uint32_t core) +{ + uint64_t coremask; + uint16_t port_id; + int rc; + + if (nb_lcore_params >= ETHDEV_RX_LCORE_PARAMS_MAX) + return -EINVAL; + + rc = rte_eth_dev_get_port_by_name(name, &port_id); + if (rc) + return -EINVAL; + + coremask = 0xff; /* FIXME: Read from graph configuration */ + + if (!(coremask & (1 << core))) + return -EINVAL; + + rx_map_configure(port_id, queue, core); + + lcore_params_array[nb_lcore_params].port_id = port_id; + lcore_params_array[nb_lcore_params].queue_id = queue; + lcore_params_array[nb_lcore_params].lcore_id = core; + nb_lcore_params++; + return 0; +} + +static void +cli_ethdev_rx_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", + "----------------------------- ethdev_rx command help -----------------------------", + cmd_ethdev_rx_help); + + len = strlen(conn->msg_out); + conn->msg_out_len_max -= len; +} + +static void +cli_ethdev_rx(void *parsed_result, __rte_unused struct cmdline *cl, void *data __rte_unused) +{ + struct ethdev_rx_cmd_tokens *res = parsed_result; + int rc = -EINVAL; + + rc = ethdev_rx_map_add(res->dev, res->qid, res->core_id); + if (rc < 0) { + cli_exit(); + printf(MSG_CMD_FAIL, res->cmd); + rte_exit(EXIT_FAILURE, "input core is Invalid\n"); + } + +} + +cmdline_parse_token_string_t ethdev_rx_cmd = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_cmd_tokens, cmd, "ethdev_rx"); +cmdline_parse_token_string_t ethdev_rx_map = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_cmd_tokens, map, "map"); +cmdline_parse_token_string_t ethdev_rx_port = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_cmd_tokens, port, "port"); +cmdline_parse_token_string_t ethdev_rx_dev = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_cmd_tokens, dev, NULL); +cmdline_parse_token_string_t ethdev_rx_queue = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_cmd_tokens, queue, "queue"); +cmdline_parse_token_num_t ethdev_rx_qid = + TOKEN_NUM_INITIALIZER(struct ethdev_rx_cmd_tokens, qid, RTE_UINT32); +cmdline_parse_token_string_t ethdev_rx_core = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_cmd_tokens, core, "core"); +cmdline_parse_token_num_t ethdev_rx_core_id = + TOKEN_NUM_INITIALIZER(struct ethdev_rx_cmd_tokens, core_id, RTE_UINT32); + +cmdline_parse_inst_t ethdev_rx_cmd_ctx = { + .f = cli_ethdev_rx, + .data = NULL, + .help_str = cmd_ethdev_rx_help, + .tokens = { + (void *)ðdev_rx_cmd, + (void *)ðdev_rx_map, + (void *)ðdev_rx_port, + (void *)ðdev_rx_dev, + (void *)ðdev_rx_queue, + (void *)ðdev_rx_qid, + (void *)ðdev_rx_core, + (void *)ðdev_rx_core_id, + NULL, + }, +}; + +cmdline_parse_token_string_t ethdev_rx_help_cmd = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_help_cmd_tokens, cmd, "help"); +cmdline_parse_token_string_t ethdev_rx_help_module = + TOKEN_STRING_INITIALIZER(struct ethdev_rx_help_cmd_tokens, module, "ethdev_rx"); + +cmdline_parse_inst_t ethdev_rx_help_cmd_ctx = { + .f = cli_ethdev_rx_help, + .data = NULL, + .help_str = "", + .tokens = { + (void *)ðdev_rx_help_cmd, + (void *)ðdev_rx_help_module, + NULL, + }, +}; diff --git a/app/graph/ethdev_rx.h b/app/graph/ethdev_rx.h new file mode 100644 index 0000000000..8e7b31448c --- /dev/null +++ b/app/graph/ethdev_rx.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#ifndef APP_GRAPH_ETHDEV_RX_H +#define APP_GRAPH_ETHDEV_RX_H + +#include <rte_graph.h> +#include <rte_node_eth_api.h> + +#define ETHDEV_RX_LCORE_PARAMS_MAX 1024 +#define ETHDEV_RX_QUEUE_PER_LCORE_MAX 16 + +struct lcore_rx_queue { + uint16_t port_id; + uint8_t queue_id; + char node_name[RTE_NODE_NAMESIZE]; +}; + +struct lcore_conf { + uint16_t n_rx_queue; + struct lcore_rx_queue rx_queue_list[ETHDEV_RX_QUEUE_PER_LCORE_MAX]; + struct rte_graph *graph; + char name[RTE_GRAPH_NAMESIZE]; + rte_graph_t graph_id; +} __rte_cache_aligned; + +uint8_t ethdev_rx_num_rx_queues_get(uint16_t port); + +extern struct rte_node_ethdev_config ethdev_conf[RTE_MAX_ETHPORTS]; +extern struct lcore_conf lcore_conf[RTE_MAX_LCORE]; +extern cmdline_parse_inst_t ethdev_rx_help_cmd_ctx; +extern cmdline_parse_inst_t ethdev_rx_cmd_ctx; +extern struct lcore_params *lcore_params; +extern uint16_t nb_lcore_params; + +#endif diff --git a/app/graph/ethdev_rx_priv.h b/app/graph/ethdev_rx_priv.h new file mode 100644 index 0000000000..5d155be043 --- /dev/null +++ b/app/graph/ethdev_rx_priv.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Marvell. + */ + +#ifndef APP_GRAPH_ETHDEV_RX_PRIV_H +#define APP_GRAPH_ETHDEV_RX_PRIV_H + +#include <stdint.h> + +#include <rte_graph.h> +#include <rte_node_eth_api.h> + +#define MAX_RX_QUEUE_PER_PORT 128 +#define MAX_JUMBO_PKT_LEN 9600 +#define NB_SOCKETS 8 + +struct ethdev_rx_cmd_tokens { + cmdline_fixed_string_t cmd; + cmdline_fixed_string_t map; + cmdline_fixed_string_t port; + cmdline_fixed_string_t dev; + cmdline_fixed_string_t queue; + cmdline_fixed_string_t core; + uint32_t core_id; + uint32_t qid; +}; + +struct ethdev_rx_help_cmd_tokens { + cmdline_fixed_string_t cmd; + cmdline_fixed_string_t module; +}; + +struct lcore_params { + uint16_t port_id; + uint8_t queue_id; + uint8_t lcore_id; +} __rte_cache_aligned; + +#endif diff --git a/app/graph/meson.build b/app/graph/meson.build index 8fa9d605b9..d8391d5cae 100644 --- a/app/graph/meson.build +++ b/app/graph/meson.build @@ -12,6 +12,7 @@ deps += ['graph', 'eal', 'lpm', 'ethdev', 'node', 'cmdline'] sources = files( 'cli.c', 'conn.c', + 'ethdev_rx.c', 'ethdev.c', 'ip4_route.c', 'ip6_route.c', diff --git a/app/graph/module_api.h b/app/graph/module_api.h index e9e42da7cc..56b7c94ecc 100644 --- a/app/graph/module_api.h +++ b/app/graph/module_api.h @@ -11,6 +11,7 @@ #include "cli.h" #include "conn.h" #include "ethdev.h" +#include "ethdev_rx.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 65aa42f500..cf738b7a39 100644 --- a/doc/guides/tools/graph.rst +++ b/doc/guides/tools/graph.rst @@ -152,6 +152,16 @@ file to express the requested use case configuration. - Command to dump neigh help message - Yes - Yes + * - ethdev_rx map port <ethdev_name> queue <q_num> core <core_id> + - Command to add port-queue-core mapping to ``ethdev_rx`` node. ``ethdev_rx`` + node instance will be pinned on given core and will poll on requested + port/queue pair. + - No + - No + * - help ethdev_rx + - Command to dump ethdev_rx help message + - Yes + - Yes Runtime configuration --------------------- -- 2.25.1