From: Alexander Kozyrev <akozyrev@nvidia.com>
To: <dev@dpdk.org>
Cc: <orika@nvidia.com>, <thomas@monjalon.net>,
<ivan.malov@oktetlabs.ru>, <andrew.rybchenko@oktetlabs.ru>,
<ferruh.yigit@intel.com>, <mohammad.abdul.awal@intel.com>,
<qi.z.zhang@intel.com>, <jerinj@marvell.com>,
<ajit.khaparde@broadcom.com>
Subject: [PATCH 04/10] app/testpmd: implement rte flow configure
Date: Tue, 18 Jan 2022 07:02:15 +0200 [thread overview]
Message-ID: <20220118050221.3914960-5-akozyrev@nvidia.com> (raw)
In-Reply-To: <20220118050221.3914960-1-akozyrev@nvidia.com>
Add testpmd support for the rte_flow_configure API.
Provide the command line interface for the Flow management.
Usage example: flow configure 0 queues_number 8 queues_size 256
Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
app/test-pmd/cmdline_flow.c | 109 +++++++++++++++++++-
app/test-pmd/config.c | 29 ++++++
app/test-pmd/testpmd.h | 5 +
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 34 +++++-
4 files changed, 174 insertions(+), 3 deletions(-)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5c2bba48ad..ea4af8dd45 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -72,6 +72,7 @@ enum index {
/* Top-level command. */
FLOW,
/* Sub-level commands. */
+ CONFIGURE,
INDIRECT_ACTION,
VALIDATE,
CREATE,
@@ -122,6 +123,13 @@ enum index {
DUMP_ALL,
DUMP_ONE,
+ /* Configure arguments */
+ CONFIG_QUEUES_NUMBER,
+ CONFIG_QUEUES_SIZE,
+ CONFIG_COUNTERS_NUMBER,
+ CONFIG_AGING_COUNTERS_NUMBER,
+ CONFIG_METERS_NUMBER,
+
/* Indirect action arguments */
INDIRECT_ACTION_CREATE,
INDIRECT_ACTION_UPDATE,
@@ -846,6 +854,10 @@ struct buffer {
enum index command; /**< Flow command. */
portid_t port; /**< Affected port ID. */
union {
+ struct {
+ struct rte_flow_port_attr port_attr;
+ struct rte_flow_queue_attr queue_attr;
+ } configure; /**< Configuration arguments. */
struct {
uint32_t *action_id;
uint32_t action_id_n;
@@ -927,6 +939,16 @@ static const enum index next_flex_item[] = {
ZERO,
};
+static const enum index next_config_attr[] = {
+ CONFIG_QUEUES_NUMBER,
+ CONFIG_QUEUES_SIZE,
+ CONFIG_COUNTERS_NUMBER,
+ CONFIG_AGING_COUNTERS_NUMBER,
+ CONFIG_METERS_NUMBER,
+ END,
+ ZERO,
+};
+
static const enum index next_ia_create_attr[] = {
INDIRECT_ACTION_CREATE_ID,
INDIRECT_ACTION_INGRESS,
@@ -1962,6 +1984,9 @@ static int parse_aged(struct context *, const struct token *,
static int parse_isolate(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_configure(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
static int parse_tunnel(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -2187,7 +2212,8 @@ static const struct token token_list[] = {
.type = "{command} {port_id} [{arg} [...]]",
.help = "manage ingress/egress flow rules",
.next = NEXT(NEXT_ENTRY
- (INDIRECT_ACTION,
+ (CONFIGURE,
+ INDIRECT_ACTION,
VALIDATE,
CREATE,
DESTROY,
@@ -2202,6 +2228,56 @@ static const struct token token_list[] = {
.call = parse_init,
},
/* Top-level command. */
+ [CONFIGURE] = {
+ .name = "configure",
+ .help = "configure flow rules",
+ .next = NEXT(next_config_attr,
+ NEXT_ENTRY(COMMON_PORT_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_configure,
+ },
+ /* Configure arguments. */
+ [CONFIG_QUEUES_NUMBER] = {
+ .name = "queues_number",
+ .help = "number of queues",
+ .next = NEXT(next_config_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.configure.port_attr.nb_queues)),
+ },
+ [CONFIG_QUEUES_SIZE] = {
+ .name = "queues_size",
+ .help = "number of elements in queues",
+ .next = NEXT(next_config_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.configure.queue_attr.size)),
+ },
+ [CONFIG_COUNTERS_NUMBER] = {
+ .name = "counters_number",
+ .help = "number of counters",
+ .next = NEXT(next_config_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.configure.port_attr.nb_counters)),
+ },
+ [CONFIG_AGING_COUNTERS_NUMBER] = {
+ .name = "aging_counters_number",
+ .help = "number of aging counters",
+ .next = NEXT(next_config_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.configure.port_attr.nb_aging)),
+ },
+ [CONFIG_METERS_NUMBER] = {
+ .name = "meters_number",
+ .help = "number of meters",
+ .next = NEXT(next_config_attr,
+ NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.configure.port_attr.nb_meters)),
+ },
+ /* Top-level command. */
[INDIRECT_ACTION] = {
.name = "indirect_action",
.type = "{command} {port_id} [{arg} [...]]",
@@ -7465,6 +7541,33 @@ parse_isolate(struct context *ctx, const struct token *token,
return len;
}
+/** Parse tokens for configure command. */
+static int
+parse_configure(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct buffer *out = buf;
+
+ /* Token name must match. */
+ if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+ return -1;
+ /* Nothing else to do if there is no buffer. */
+ if (!out)
+ return len;
+ if (!out->command) {
+ if (ctx->curr != CONFIGURE)
+ return -1;
+ if (sizeof(*out) > size)
+ return -1;
+ out->command = ctx->curr;
+ ctx->objdata = 0;
+ ctx->object = out;
+ ctx->objmask = NULL;
+ }
+ return len;
+}
+
static int
parse_flex(struct context *ctx, const struct token *token,
const char *str, unsigned int len,
@@ -8691,6 +8794,10 @@ static void
cmd_flow_parsed(const struct buffer *in)
{
switch (in->command) {
+ case CONFIGURE:
+ port_flow_configure(in->port, &in->args.configure.port_attr,
+ &in->args.configure.queue_attr);
+ break;
case INDIRECT_ACTION_CREATE:
port_action_handle_create(
in->port, in->args.vc.attr.group,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 1722d6c8f8..85d31de7f7 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1595,6 +1595,35 @@ action_alloc(portid_t port_id, uint32_t id,
return 0;
}
+/** Configure flow management resources. */
+int
+port_flow_configure(portid_t port_id,
+ const struct rte_flow_port_attr *port_attr,
+ const struct rte_flow_queue_attr *queue_attr)
+{
+ struct rte_port *port;
+ struct rte_flow_error error;
+ const struct rte_flow_queue_attr *attr_list[port_attr->nb_queues];
+ int std_queue;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ port->queue_nb = port_attr->nb_queues;
+ port->queue_sz = queue_attr->size;
+ for (std_queue = 0; std_queue < port_attr->nb_queues; std_queue++)
+ attr_list[std_queue] = queue_attr;
+ /* Poisoning to make sure PMDs update it in case of error. */
+ memset(&error, 0x66, sizeof(error));
+ if (rte_flow_configure(port_id, port_attr, attr_list, &error))
+ return port_flow_complain(&error);
+ printf("Configure flows on port %u: "
+ "number of queues %d with %d elements\n",
+ port_id, port_attr->nb_queues, queue_attr->size);
+ return 0;
+}
+
/** Create indirect action */
int
port_action_handle_create(portid_t port_id, uint32_t id,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9967825044..ce80a00193 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -243,6 +243,8 @@ struct rte_port {
struct rte_eth_txconf tx_conf[RTE_MAX_QUEUES_PER_PORT+1]; /**< per queue tx configuration */
struct rte_ether_addr *mc_addr_pool; /**< pool of multicast addrs */
uint32_t mc_addr_nb; /**< nb. of addr. in mc_addr_pool */
+ queueid_t queue_nb; /**< nb. of queues for flow rules */
+ uint32_t queue_sz; /**< size of a queue for flow rules */
uint8_t slave_flag; /**< bonding slave port */
struct port_flow *flow_list; /**< Associated flows. */
struct port_indirect_action *actions_list;
@@ -885,6 +887,9 @@ struct rte_flow_action_handle *port_action_handle_get_by_id(portid_t port_id,
uint32_t id);
int port_action_handle_update(portid_t port_id, uint32_t id,
const struct rte_flow_action *action);
+int port_flow_configure(portid_t port_id,
+ const struct rte_flow_port_attr *port_attr,
+ const struct rte_flow_queue_attr *queue_attr);
int port_flow_validate(portid_t port_id,
const struct rte_flow_attr *attr,
const struct rte_flow_item *pattern,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 94792d88cc..8af28bd3b3 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3285,8 +3285,8 @@ Flow rules management
---------------------
Control of the generic flow API (*rte_flow*) is fully exposed through the
-``flow`` command (validation, creation, destruction, queries and operation
-modes).
+``flow`` command (configuration, validation, creation, destruction, queries
+and operation modes).
Considering *rte_flow* overlaps with all `Filter Functions`_, using both
features simultaneously may cause undefined side-effects and is therefore
@@ -3309,6 +3309,14 @@ The first parameter stands for the operation mode. Possible operations and
their general syntax are described below. They are covered in detail in the
following sections.
+- Configure flow management::
+
+ flow configure {port_id}
+ [queues_number {number}] [queues_size {size}]
+ [counters_number {number}]
+ [aging_counters_number {number}]
+ [meters_number {number}]
+
- Check whether a flow rule can be created::
flow validate {port_id}
@@ -3368,6 +3376,28 @@ following sections.
flow tunnel list {port_id}
+Configuring flow management library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``flow configure`` pre-allocates all the needed resources in the underlying
+device to be used later at the flow creation. Flow queues are allocated as well
+for asynchronous flow creation/destruction operations. It is bound to
+``rte_flow_configure()``::
+
+ flow configure {port_id}
+ [queues_number {number}] [queues_size {size}]
+ [counters_number {number}]
+ [aging_counters_number {number}]
+ [meters_number {number}]
+
+If successful, it will show::
+
+ Configure flows on port #[...]: number of queues #[...] with #[...] elements
+
+Otherwise it will show an error message of the form::
+
+ Caught error type [...] ([...]): [...]
+
Creating a tunnel stub for offload
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
2.18.2
prev parent reply other threads:[~2022-01-18 5:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-18 5:02 [PATCH 00/10] ethdev: datapath-focused flow rules management Alexander Kozyrev
2022-01-18 5:02 ` [PATCH 01/10] ethdev: introduce flow pre-configuration hints Alexander Kozyrev
2022-01-18 5:02 ` [PATCH 02/10] ethdev: add flow item/action templates Alexander Kozyrev
2022-01-18 5:02 ` [PATCH 03/10] ethdev: bring in async queue-based flow rules operations Alexander Kozyrev
2022-01-18 5:02 ` Alexander Kozyrev [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220118050221.3914960-5-akozyrev@nvidia.com \
--to=akozyrev@nvidia.com \
--cc=ajit.khaparde@broadcom.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=ivan.malov@oktetlabs.ru \
--cc=jerinj@marvell.com \
--cc=mohammad.abdul.awal@intel.com \
--cc=orika@nvidia.com \
--cc=qi.z.zhang@intel.com \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).