From: Gregory Etelson <getelson@nvidia.com>
To: <dev@dpdk.org>
Cc: <getelson@nvidia.com>, <mkashani@nvidia.com>,
Ori Kam <orika@nvidia.com>,
Aman Singh <aman.deep.singh@intel.com>,
Yuying Zhang <yuying.zhang@intel.com>,
Thomas Monjalon <thomas@monjalon.net>,
Ferruh Yigit <ferruh.yigit@amd.com>,
Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Subject: [PATCH] ethdev: add template table resize API
Date: Sun, 17 Dec 2023 11:32:04 +0200 [thread overview]
Message-ID: <20231217093205.321082-1-getelson@nvidia.com> (raw)
Template table creation API sets table flows capacity.
If application needs more flows then the table was designed for,
the following procedures must be completed:
1. Create a new template table with larger flows capacity.
2. Re-create existing flows in the new table and delete flows from
the original table.
3. Destroy original table.
Application cannot always execute that procedure:
* Port may not have sufficient resources to allocate a new table
while maintaining original table.
* Application may not have existing flows "recipes" to re-create
flows in a new table.
The patch defines a new API that allows application to resize
existing template table:
* Resizable template table must be created with the
RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE_TABLE bit set.
* Application resizes existing table with the
`rte_flow_template_table_resize()` function call.
The table resize procedure updates the table maximal flow number
only. Other table attributes are not affected by the table resize.
** The table resize procedure must not interrupt
existing table flows operations in hardware.
** The table resize procedure must not alter flow handlers held by
application.
* After `rte_flow_template_table_resize()` returned, application must
update all existing table flow rules by calling
`rte_flow_async_update_resized()`.
The table resize procedure does not change application flow handler.
However, flow object can reference internal PMD resources that are
obsolete after table resize.
`rte_flow_async_update_resized()` moves internal flow references
to the updated table resources.
The flow update must not interrupt hardware flow operations.
* When all table flow were updated, application must call
`rte_flow_template_table_resize_complete()`.
The function releases PMD resources related to the original
table.
Application can start new table resize after
`rte_flow_template_table_resize_complete()` returned.
Signed-off-by: Gregory Etelson <getelson@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
app/test-pmd/cmdline_flow.c | 86 +++++++++++++++++++--
app/test-pmd/config.c | 102 +++++++++++++++++++++++++
app/test-pmd/testpmd.h | 6 ++
doc/guides/rel_notes/release_24_03.rst | 2 +
lib/ethdev/ethdev_trace.h | 33 ++++++++
lib/ethdev/ethdev_trace_points.c | 9 +++
lib/ethdev/rte_flow.c | 69 +++++++++++++++++
lib/ethdev/rte_flow.h | 97 +++++++++++++++++++++++
lib/ethdev/rte_flow_driver.h | 15 ++++
lib/ethdev/version.map | 3 +
10 files changed, 417 insertions(+), 5 deletions(-)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ce71818705..a34757a13e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -134,6 +134,7 @@ enum index {
/* Queue arguments. */
QUEUE_CREATE,
QUEUE_DESTROY,
+ QUEUE_FLOW_UPDATE_RESIZED,
QUEUE_UPDATE,
QUEUE_AGED,
QUEUE_INDIRECT_ACTION,
@@ -191,8 +192,12 @@ enum index {
/* Table arguments. */
TABLE_CREATE,
TABLE_DESTROY,
+ TABLE_RESIZE,
+ TABLE_RESIZE_COMPLETE,
TABLE_CREATE_ID,
TABLE_DESTROY_ID,
+ TABLE_RESIZE_ID,
+ TABLE_RESIZE_RULES_NUMBER,
TABLE_INSERTION_TYPE,
TABLE_INSERTION_TYPE_NAME,
TABLE_HASH_FUNC,
@@ -204,6 +209,7 @@ enum index {
TABLE_TRANSFER,
TABLE_TRANSFER_WIRE_ORIG,
TABLE_TRANSFER_VPORT_ORIG,
+ TABLE_RESIZABLE,
TABLE_RULES_NUMBER,
TABLE_PATTERN_TEMPLATE,
TABLE_ACTIONS_TEMPLATE,
@@ -1323,6 +1329,8 @@ static const enum index next_group_attr[] = {
static const enum index next_table_subcmd[] = {
TABLE_CREATE,
TABLE_DESTROY,
+ TABLE_RESIZE,
+ TABLE_RESIZE_COMPLETE,
ZERO,
};
@@ -1337,6 +1345,7 @@ static const enum index next_table_attr[] = {
TABLE_TRANSFER,
TABLE_TRANSFER_WIRE_ORIG,
TABLE_TRANSFER_VPORT_ORIG,
+ TABLE_RESIZABLE,
TABLE_RULES_NUMBER,
TABLE_PATTERN_TEMPLATE,
TABLE_ACTIONS_TEMPLATE,
@@ -1353,6 +1362,7 @@ static const enum index next_table_destroy_attr[] = {
static const enum index next_queue_subcmd[] = {
QUEUE_CREATE,
QUEUE_DESTROY,
+ QUEUE_FLOW_UPDATE_RESIZED,
QUEUE_UPDATE,
QUEUE_AGED,
QUEUE_INDIRECT_ACTION,
@@ -3344,6 +3354,19 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
.call = parse_table_destroy,
},
+ [TABLE_RESIZE] = {
+ .name = "resize",
+ .help = "resize template table",
+ .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)),
+ .call = parse_table
+ },
+ [TABLE_RESIZE_COMPLETE] = {
+ .name = "resize_complete",
+ .help = "complete table resize",
+ .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+ .call = parse_table_destroy,
+ },
/* Table arguments. */
[TABLE_CREATE_ID] = {
.name = "table_id",
@@ -3354,13 +3377,29 @@ static const struct token token_list[] = {
},
[TABLE_DESTROY_ID] = {
.name = "table",
- .help = "specify table id to destroy",
+ .help = "table id",
.next = NEXT(next_table_destroy_attr,
NEXT_ENTRY(COMMON_TABLE_ID)),
.args = ARGS(ARGS_ENTRY_PTR(struct buffer,
args.table_destroy.table_id)),
.call = parse_table_destroy,
},
+ [TABLE_RESIZE_ID] = {
+ .name = "table_resize_id",
+ .help = "table resize id",
+ .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER),
+ NEXT_ENTRY(COMMON_TABLE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)),
+ .call = parse_table
+ },
+ [TABLE_RESIZE_RULES_NUMBER] = {
+ .name = "table_resize_rules_num",
+ .help = "table resize rules number",
+ .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY(struct buffer,
+ args.table.attr.nb_flows)),
+ .call = parse_table
+ },
[TABLE_INSERTION_TYPE] = {
.name = "insertion_type",
.help = "specify insertion type",
@@ -3433,6 +3472,12 @@ static const struct token token_list[] = {
.next = NEXT(next_table_attr),
.call = parse_table,
},
+ [TABLE_RESIZABLE] = {
+ .name = "resizable",
+ .help = "set resizable attribute",
+ .next = NEXT(next_table_attr),
+ .call = parse_table,
+ },
[TABLE_RULES_NUMBER] = {
.name = "rules_number",
.help = "number of rules in table",
@@ -3525,6 +3570,14 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
.call = parse_qo_destroy,
},
+ [QUEUE_FLOW_UPDATE_RESIZED] = {
+ .name = "update_resized",
+ .help = "update a flow after table resize",
+ .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID),
+ NEXT_ENTRY(COMMON_QUEUE_ID)),
+ .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+ .call = parse_qo_destroy,
+ },
[QUEUE_UPDATE] = {
.name = "update",
.help = "update a flow rule",
@@ -10334,6 +10387,7 @@ parse_table(struct context *ctx, const struct token *token,
}
switch (ctx->curr) {
case TABLE_CREATE:
+ case TABLE_RESIZE:
out->command = ctx->curr;
ctx->objdata = 0;
ctx->object = out;
@@ -10378,18 +10432,25 @@ parse_table(struct context *ctx, const struct token *token,
case TABLE_TRANSFER_WIRE_ORIG:
if (!out->args.table.attr.flow_attr.transfer)
return -1;
- out->args.table.attr.specialize = RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG;
+ out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG;
return len;
case TABLE_TRANSFER_VPORT_ORIG:
if (!out->args.table.attr.flow_attr.transfer)
return -1;
- out->args.table.attr.specialize = RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG;
+ out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG;
+ return len;
+ case TABLE_RESIZABLE:
+ out->args.table.attr.specialize |=
+ RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE_TABLE;
return len;
case TABLE_RULES_NUMBER:
ctx->objdata = 0;
ctx->object = out;
ctx->objmask = NULL;
return len;
+ case TABLE_RESIZE_ID:
+ case TABLE_RESIZE_RULES_NUMBER:
+ return len;
default:
return -1;
}
@@ -10411,7 +10472,8 @@ parse_table_destroy(struct context *ctx, const struct token *token,
if (!out)
return len;
if (!out->command || out->command == TABLE) {
- if (ctx->curr != TABLE_DESTROY)
+ if (ctx->curr != TABLE_DESTROY &&
+ ctx->curr != TABLE_RESIZE_COMPLETE)
return -1;
if (sizeof(*out) > size)
return -1;
@@ -10513,7 +10575,8 @@ parse_qo_destroy(struct context *ctx, const struct token *token,
if (!out)
return len;
if (!out->command || out->command == QUEUE) {
- if (ctx->curr != QUEUE_DESTROY)
+ if (ctx->curr != QUEUE_DESTROY &&
+ ctx->curr != QUEUE_FLOW_UPDATE_RESIZED)
return -1;
if (sizeof(*out) > size)
return -1;
@@ -12569,10 +12632,18 @@ cmd_flow_parsed(const struct buffer *in)
in->args.table_destroy.table_id_n,
in->args.table_destroy.table_id);
break;
+ case TABLE_RESIZE_COMPLETE:
+ port_flow_template_table_resize_complete
+ (in->port, in->args.table_destroy.table_id[0]);
+ break;
case GROUP_SET_MISS_ACTIONS:
port_queue_group_set_miss_actions(in->port, &in->args.vc.attr,
in->args.vc.actions);
break;
+ case TABLE_RESIZE:
+ port_flow_template_table_resize(in->port, in->args.table.id,
+ in->args.table.attr.nb_flows);
+ break;
case QUEUE_CREATE:
port_queue_flow_create(in->port, in->queue, in->postpone,
in->args.vc.table_id, in->args.vc.rule_id,
@@ -12584,6 +12655,11 @@ cmd_flow_parsed(const struct buffer *in)
in->args.destroy.rule_n,
in->args.destroy.rule);
break;
+ case QUEUE_FLOW_UPDATE_RESIZED:
+ port_queue_flow_update_resized(in->port, in->queue,
+ in->postpone,
+ in->args.destroy.rule[0]);
+ break;
case QUEUE_UPDATE:
port_queue_flow_update(in->port, in->queue, in->postpone,
in->args.vc.rule_id, in->args.vc.act_templ_id,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index cad7537bc6..e589ac614b 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1403,6 +1403,19 @@ port_flow_new(const struct rte_flow_attr *attr,
return NULL;
}
+static struct port_flow *
+port_flow_locate(struct port_flow *flows_list, uint32_t flow_id)
+{
+ struct port_flow *pf = flows_list;
+
+ while (pf) {
+ if (pf->id == flow_id)
+ break;
+ pf = pf->next;
+ }
+ return pf;
+}
+
/** Print a message out of a flow error. */
static int
port_flow_complain(struct rte_flow_error *error)
@@ -1693,6 +1706,19 @@ table_alloc(uint32_t id, struct port_table **table,
return 0;
}
+static struct port_table *
+port_table_locate(struct port_table *tables_list, uint32_t table_id)
+{
+ struct port_table *pt = tables_list;
+
+ while (pt) {
+ if (pt->id == table_id)
+ break;
+ pt = pt->next;
+ }
+ return pt;
+}
+
/** Get info about flow management resources. */
int
port_flow_get_info(portid_t port_id)
@@ -2665,6 +2691,46 @@ port_flow_template_table_destroy(portid_t port_id,
return ret;
}
+int
+port_flow_template_table_resize_complete(portid_t port_id, uint32_t table_id)
+{
+ struct rte_port *port;
+ struct port_table *pt;
+ struct rte_flow_error error = { 0, };
+ int ret;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return -EINVAL;
+ port = &ports[port_id];
+ pt = port_table_locate(port->table_list, table_id);
+ if (!pt)
+ return -EINVAL;
+ ret = rte_flow_template_table_resize_complete(port_id,
+ pt->table, &error);
+ return !ret ? 0 : port_flow_complain(&error);
+}
+
+int
+port_flow_template_table_resize(portid_t port_id,
+ uint32_t table_id, uint32_t flows_num)
+{
+ struct rte_port *port;
+ struct port_table *pt;
+ struct rte_flow_error error = { 0, };
+ int ret;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return -EINVAL;
+ port = &ports[port_id];
+ pt = port_table_locate(port->table_list, table_id);
+ if (!pt)
+ return -EINVAL;
+ ret = rte_flow_template_table_resize(port_id, pt->table, flows_num, &error);
+ if (ret)
+ return port_flow_complain(&error);
+ return 0;
+}
+
/** Flush table */
int
port_flow_template_table_flush(portid_t port_id)
@@ -2805,6 +2871,42 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id,
return 0;
}
+int
+port_queue_flow_update_resized(portid_t port_id, queueid_t queue_id,
+ bool postpone, uint32_t flow_id)
+{
+ const struct rte_flow_op_attr op_attr = { .postpone = postpone };
+ struct rte_flow_error error = { 0, };
+ struct port_flow *pf;
+ struct rte_port *port;
+ struct queue_job *job;
+ int ret;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN) ||
+ port_id == (portid_t)RTE_PORT_ALL)
+ return -EINVAL;
+ port = &ports[port_id];
+ if (queue_id >= port->queue_nb) {
+ printf("Queue #%u is invalid\n", queue_id);
+ return -EINVAL;
+ }
+ pf = port_flow_locate(port->flow_list, flow_id);
+ if (!pf)
+ return -EINVAL;
+ job = calloc(1, sizeof(*job));
+ if (!job)
+ return -ENOMEM;
+ job->type = QUEUE_JOB_TYPE_FLOW_TRANSFER;
+ job->pf = pf;
+ ret = rte_flow_async_update_resized(port_id, queue_id, &op_attr,
+ pf->flow, job, &error);
+ if (ret) {
+ free(job);
+ return port_flow_complain(&error);
+ }
+ return 0;
+}
+
/** Enqueue number of destroy flow rules operations. */
int
port_queue_flow_destroy(portid_t port_id, queueid_t queue_id,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9b10a9ea1c..92f21e7776 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -110,6 +110,7 @@ enum {
enum {
QUEUE_JOB_TYPE_FLOW_CREATE,
QUEUE_JOB_TYPE_FLOW_DESTROY,
+ QUEUE_JOB_TYPE_FLOW_TRANSFER,
QUEUE_JOB_TYPE_FLOW_UPDATE,
QUEUE_JOB_TYPE_ACTION_CREATE,
QUEUE_JOB_TYPE_ACTION_DESTROY,
@@ -981,7 +982,12 @@ int port_flow_template_table_create(portid_t port_id, uint32_t id,
uint32_t nb_actions_templates, uint32_t *actions_templates);
int port_flow_template_table_destroy(portid_t port_id,
uint32_t n, const uint32_t *table);
+int port_queue_flow_update_resized(portid_t port_id, queueid_t queue_id,
+ bool postpone, uint32_t flow_id);
int port_flow_template_table_flush(portid_t port_id);
+int port_flow_template_table_resize_complete(portid_t port_id, uint32_t table_id);
+int port_flow_template_table_resize(portid_t port_id,
+ uint32_t table_id, uint32_t flows_num);
int port_queue_group_set_miss_actions(portid_t port_id, const struct rte_flow_attr *attr,
const struct rte_flow_action *actions);
int port_queue_flow_create(portid_t port_id, queueid_t queue_id,
diff --git a/doc/guides/rel_notes/release_24_03.rst b/doc/guides/rel_notes/release_24_03.rst
index e9c9717706..8ad1891396 100644
--- a/doc/guides/rel_notes/release_24_03.rst
+++ b/doc/guides/rel_notes/release_24_03.rst
@@ -55,6 +55,8 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+* **Added support for template API table resize.**
+
Removed Items
-------------
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 1b1ae0cfe8..cd3327a619 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -2572,6 +2572,39 @@ RTE_TRACE_POINT_FP(
rte_trace_point_emit_ptr(user_data);
rte_trace_point_emit_int(ret);
)
+
+RTE_TRACE_POINT_FP(
+ rte_flow_trace_template_table_resize,
+ RTE_TRACE_POINT_ARGS(uint16_t port_id,
+ struct rte_flow_template_table *table,
+ uint32_t nb_rules, int ret),
+ rte_trace_point_emit_u16(port_id);
+ rte_trace_point_emit_ptr(table);
+ rte_trace_point_emit_u32(nb_rules);
+ rte_trace_point_emit_int(ret);
+)
+
+RTE_TRACE_POINT_FP(
+ rte_flow_trace_async_update_resized,
+ RTE_TRACE_POINT_ARGS(uint16_t port_id, uint32_t queue,
+ const struct rte_flow_op_attr *attr,
+ struct rte_flow *rule, void *user_data, int ret),
+ rte_trace_point_emit_u16(port_id);
+ rte_trace_point_emit_u32(queue);
+ rte_trace_point_emit_ptr(attr);
+ rte_trace_point_emit_ptr(rule);
+ rte_trace_point_emit_ptr(user_data);
+ rte_trace_point_emit_int(ret);
+)
+
+RTE_TRACE_POINT_FP(
+ rte_flow_trace_table_resize_complete,
+ RTE_TRACE_POINT_ARGS(uint16_t port_id,
+ struct rte_flow_template_table *table, int ret),
+ rte_trace_point_emit_u16(port_id);
+ rte_trace_point_emit_ptr(table);
+ rte_trace_point_emit_int(ret);
+)
#ifdef __cplusplus
}
#endif
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 91f71d868b..1a1f685daa 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -774,3 +774,12 @@ RTE_TRACE_POINT_REGISTER(rte_flow_trace_async_action_list_handle_destroy,
RTE_TRACE_POINT_REGISTER(rte_flow_trace_async_action_list_handle_query_update,
lib.ethdev.flow.async_action_list_handle_query_update)
+
+RTE_TRACE_POINT_REGISTER(rte_flow_trace_template_table_resize,
+ lib.ethdev.flow.template_table_resize)
+
+RTE_TRACE_POINT_REGISTER(rte_flow_trace_async_update_resized,
+ lib.ethdev.flow.async_update_resized)
+
+RTE_TRACE_POINT_REGISTER(rte_flow_trace_table_resize_complete,
+ lib.ethdev.flow.table_resize_complete)
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 549e329558..3a46a81f44 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -2479,3 +2479,72 @@ rte_flow_calc_table_hash(uint16_t port_id, const struct rte_flow_template_table
hash, error);
return flow_err(port_id, ret, error);
}
+
+int
+rte_flow_template_table_resize(uint16_t port_id,
+ struct rte_flow_template_table *table,
+ uint32_t nb_rules,
+ struct rte_flow_error *error)
+{
+ int ret;
+ struct rte_eth_dev *dev;
+ const struct rte_flow_ops *ops;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ ops = rte_flow_ops_get(port_id, error);
+ if (!ops || !ops->flow_template_table_resize)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "flow_template_table_resize not supported");
+ dev = &rte_eth_devices[port_id];
+ ret = ops->flow_template_table_resize(dev, table, nb_rules, error);
+ ret = flow_err(port_id, ret, error);
+ rte_flow_trace_template_table_resize(port_id, table, nb_rules, ret);
+ return ret;
+}
+
+int
+rte_flow_async_update_resized(uint16_t port_id, uint32_t queue,
+ const struct rte_flow_op_attr *attr,
+ struct rte_flow *rule, void *user_data,
+ struct rte_flow_error *error)
+{
+ int ret;
+ struct rte_eth_dev *dev;
+ const struct rte_flow_ops *ops;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ ops = rte_flow_ops_get(port_id, error);
+ if (!ops || !ops->flow_update_resized)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "async_flow_async_transfer not supported");
+ dev = &rte_eth_devices[port_id];
+ ret = ops->flow_update_resized(dev, queue, attr, rule, user_data, error);
+ ret = flow_err(port_id, ret, error);
+ rte_flow_trace_async_update_resized(port_id, queue, attr,
+ rule, user_data, ret);
+ return ret;
+}
+
+int
+rte_flow_template_table_resize_complete(uint16_t port_id,
+ struct rte_flow_template_table *table,
+ struct rte_flow_error *error)
+{
+ int ret;
+ struct rte_eth_dev *dev;
+ const struct rte_flow_ops *ops;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ ops = rte_flow_ops_get(port_id, error);
+ if (!ops || !ops->flow_template_table_resize_complete)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "flow_template_table_transfer_complete not supported");
+ dev = &rte_eth_devices[port_id];
+ ret = ops->flow_template_table_resize_complete(dev, table, error);
+ ret = flow_err(port_id, ret, error);
+ rte_flow_trace_table_resize_complete(port_id, table, ret);
+ return ret;
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index affdc8121b..0b5de9b20b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5749,6 +5749,10 @@ struct rte_flow_template_table;
* if the hint is supported.
*/
#define RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG RTE_BIT32(1)
+/**
+ * Specialize table for resize.
+ */
+#define RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE_TABLE RTE_BIT32(2)
/**@}*/
/**
@@ -5827,6 +5831,13 @@ struct rte_flow_template_table_attr {
enum rte_flow_table_hash_func hash_func;
};
+static __rte_always_inline bool
+rte_flow_table_resizable(const struct rte_flow_template_table_attr *tbl_attr)
+{
+ return (tbl_attr->specialize &
+ RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE_TABLE) != 0;
+}
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
@@ -6753,6 +6764,92 @@ rte_flow_calc_table_hash(uint16_t port_id, const struct rte_flow_template_table
const struct rte_flow_item pattern[], uint8_t pattern_template_index,
uint32_t *hash, struct rte_flow_error *error);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Change template table flow rules capacity.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param table
+ * Template table to modify.
+ * @param nb_rules
+ * New flow rules capacity.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * - (0) if success.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) if *table* cannot be resized or invalid *nb_rules*
+ */
+__rte_experimental
+int
+rte_flow_template_table_resize(uint16_t port_id,
+ struct rte_flow_template_table *table,
+ uint32_t nb_rules,
+ struct rte_flow_error *error);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Following table resize, update flow resources in port.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param queue
+ * Flow queue for async operation.
+ * @param attr
+ * Async operation attributes.
+ * @param rule
+ * Flow rule to update.
+ * @param user_data
+ * The user data that will be returned on async completion event.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * - (0) if success.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) if *rule* cannot be updated.
+ */
+__rte_experimental
+int
+rte_flow_async_update_resized(uint16_t port_id, uint32_t queue,
+ const struct rte_flow_op_attr *attr,
+ struct rte_flow *rule, void *user_data,
+ struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Following table resize, notify port that all table flows were updated.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param table
+ * Template table that undergoing resize operation.
+ * @param error
+ * Perform verbose error reporting if not NULL.
+ * PMDs initialize this structure in case of error only.
+ *
+ * @return
+ * - (0) if success.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-ENOTSUP) if underlying device does not support this functionality.
+ * - (-EINVAL) PMD cannot complete table resize.
+ */
+__rte_experimental
+int
+rte_flow_template_table_resize_complete(uint16_t port_id,
+ struct rte_flow_template_table *table,
+ struct rte_flow_error *error);
#ifdef __cplusplus
}
#endif
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index f35f659503..53d9393575 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -370,6 +370,21 @@ struct rte_flow_ops {
(struct rte_eth_dev *dev, const struct rte_flow_template_table *table,
const struct rte_flow_item pattern[], uint8_t pattern_template_index,
uint32_t *hash, struct rte_flow_error *error);
+ /** @see rte_flow_template_table_resize() */
+ int (*flow_template_table_resize)(struct rte_eth_dev *dev,
+ struct rte_flow_template_table *table,
+ uint32_t nb_rules,
+ struct rte_flow_error *error);
+ /** @see rte_flow_async_update_resized() */
+ int (*flow_update_resized)(struct rte_eth_dev *dev, uint32_t queue,
+ const struct rte_flow_op_attr *attr,
+ struct rte_flow *rule, void *user_data,
+ struct rte_flow_error *error);
+ /** @see rte_flow_template_table_resize_complete() */
+ int (*flow_template_table_resize_complete)
+ (struct rte_eth_dev *dev,
+ struct rte_flow_template_table *table,
+ struct rte_flow_error *error);
};
/**
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 5c4917c020..e37bab9b81 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -316,6 +316,9 @@ EXPERIMENTAL {
rte_eth_recycle_rx_queue_info_get;
rte_flow_group_set_miss_actions;
rte_flow_calc_table_hash;
+ rte_flow_template_table_resize;
+ rte_flow_async_update_resized;
+ rte_flow_template_table_resize_complete;
};
INTERNAL {
--
2.39.2
next reply other threads:[~2023-12-17 9:32 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-17 9:32 Gregory Etelson [this message]
2024-01-29 14:24 ` Ferruh Yigit
2024-01-29 15:08 ` Etelson, Gregory
2024-01-30 8:58 ` Ferruh Yigit
2024-01-30 12:46 ` Etelson, Gregory
2024-01-30 14:34 ` Ferruh Yigit
2024-01-30 18:15 ` Etelson, Gregory
2024-02-08 12:46 ` Ferruh Yigit
2024-02-09 5:55 ` Etelson, Gregory
2024-01-30 14:56 ` Ferruh Yigit
2024-01-30 18:49 ` Etelson, Gregory
2024-01-31 9:59 ` [PATCH v2] " Gregory Etelson
2024-02-06 22:31 ` Thomas Monjalon
2024-02-07 7:09 ` Etelson, Gregory
2024-02-07 7:03 ` [PATCH v3] " Gregory Etelson
2024-02-07 17:36 ` [PATCH v4] " Gregory Etelson
2024-02-11 9:30 ` [PATCH v5] " Gregory Etelson
2024-02-12 14:02 ` Thomas Monjalon
2024-02-12 14:48 ` Etelson, Gregory
2024-02-12 14:14 ` Ferruh Yigit
2024-02-12 15:01 ` Etelson, Gregory
2024-02-12 15:07 ` Ferruh Yigit
2024-02-12 18:12 ` [PATCH v6] " Gregory Etelson
2024-02-12 20:30 ` Ferruh Yigit
2024-02-13 11:51 ` Thomas Monjalon
2024-02-14 14:32 ` [PATCH v7] " Gregory Etelson
2024-02-14 14:42 ` Thomas Monjalon
2024-02-14 15:56 ` Ferruh Yigit
2024-02-14 17:07 ` Etelson, Gregory
2024-02-14 21:59 ` Ferruh Yigit
2024-02-15 5:41 ` Etelson, Gregory
2024-02-15 6:13 ` [PATCH v8] " Gregory Etelson
2024-02-15 13:13 ` Ferruh Yigit
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=20231217093205.321082-1-getelson@nvidia.com \
--to=getelson@nvidia.com \
--cc=aman.deep.singh@intel.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=mkashani@nvidia.com \
--cc=orika@nvidia.com \
--cc=thomas@monjalon.net \
--cc=yuying.zhang@intel.com \
/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).