summaryrefslogtreecommitdiff
path: root/lib/ethdev
diff options
context:
space:
mode:
authorGregory Etelson <[email protected]>2024-02-15 08:13:08 +0200
committerFerruh Yigit <[email protected]>2024-02-15 12:55:21 +0100
commit99231e480b69e2e722ae976c69e0c5dd4b37122a (patch)
tree611b5d2b3fae4e204ed30cb1d0305e2f50fd597d /lib/ethdev
parentaa3e97fcb55d7b68fef864aa76078bdae375ad3d (diff)
ethdev: add template table resize
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 handles held by application. * After `rte_flow_template_table_resize()` returned, application must update table flow rules by calling `rte_flow_async_update_resized()`. The call reconfigures internal flow resources for the new table configuration. The flow update must not interrupt hardware flow operations. * After table flows 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. Testpmd commands: * Create resizable template table flow template_table <port-id> create table_id <tbl-id> resizable \ [transfer|ingress|egres] group <group-id> \ rules_number <initial table capacity> \ pattern_template <pt1> [ pattern_template <pt2> [ ... ]] \ actions_template <at1> [ actions_template <at2> [ ... ]] * Resize table: flow template_table <tbl-id> resize table_resize_id <tbl-id> \ table_resize_rules_num <new table capacity> * Queue a flow update: flow queue <port-id> update_resized <tbl-id> rule <flow-id> * Complete table resize: flow template_table <port-id> resize_complete table <tbl-id> Signed-off-by: Gregory Etelson <[email protected]> Acked-by: Ori Kam <[email protected]> Acked-by: Ferruh Yigit <[email protected]> Acked-by: Thomas Monjalon <[email protected]>
Diffstat (limited to 'lib/ethdev')
-rw-r--r--lib/ethdev/ethdev_trace.h34
-rw-r--r--lib/ethdev/ethdev_trace_points.c9
-rw-r--r--lib/ethdev/rte_flow.c77
-rw-r--r--lib/ethdev/rte_flow.h119
-rw-r--r--lib/ethdev/rte_flow_driver.h15
-rw-r--r--lib/ethdev/version.map4
6 files changed, 258 insertions, 0 deletions
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 1b1ae0cfe8..3bec87bfdb 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -2572,6 +2572,40 @@ 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 bd6dd4e78a..99e04f5893 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -777,3 +777,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 a26758d6d4..7ab1100ea0 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -2591,6 +2591,83 @@ rte_flow_calc_encap_hash(uint16_t port_id, const struct rte_flow_item pattern[],
return flow_err(port_id, ret, error);
}
+bool
+rte_flow_template_table_resizable(__rte_unused uint16_t port_id,
+ const struct rte_flow_template_table_attr *tbl_attr)
+{
+ return (tbl_attr->specialize &
+ RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE) != 0;
+}
+
+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;
+}
+
static struct rte_flow *
rte_flow_dummy_async_create(struct rte_eth_dev *dev __rte_unused,
uint32_t queue __rte_unused,
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 44f5db0c6a..dc827cdea0 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -5842,6 +5842,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 RTE_BIT32(2)
/**@}*/
/**
@@ -5924,6 +5928,25 @@ struct rte_flow_template_table_attr {
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
+ * Query whether a table can be resized.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param tbl_attr
+ * Template table.
+ *
+ * @return
+ * True if the table can be resized.
+ */
+__rte_experimental
+bool
+rte_flow_template_table_resizable(__rte_unused uint16_t port_id,
+ const struct rte_flow_template_table_attr *tbl_attr);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
* Create flow template table.
*
* A template table consists of multiple pattern templates and actions
@@ -6899,6 +6922,102 @@ rte_flow_calc_encap_hash(uint16_t port_id, const struct rte_flow_item pattern[],
enum rte_flow_encap_hash_field dest_field, uint8_t hash_len,
uint8_t *hash, struct rte_flow_error *error);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Update template table for new 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* is not resizable or
+ * *table* resize to *nb_rules* is not supported or
+ * unrecoverable *table* error.
+ */
+__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.
+ *
+ * Update *rule* for the new *table* configuration after table resize.
+ * Must be called for each *rule* created before *table* resize.
+ * If called for *rule* created after *table* resize returns success.
+ *
+ * @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 *table* was not resized.
+ * If *rule* cannot be updated after *table* resize,
+ * unrecoverable *table* error.
+ */
+__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.
+ *
+ * Resume normal operational mode after table was resized and
+ * table rules were updated for the new table configuration.
+ *
+ * @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.
+ * - (-EBUSY) if not all *table* rules were updated.
+ * - (-EINVAL) if *table* cannot complete table resize,
+ * unrecoverable error.
+ */
+__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 ac55b762a0..3c702e30b4 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -257,6 +257,21 @@ struct rte_flow_ops {
(struct rte_eth_dev *dev, const struct rte_flow_item pattern[],
enum rte_flow_encap_hash_field dest_field, uint8_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 864b75e73e..17e4eac8a4 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -320,7 +320,11 @@ EXPERIMENTAL {
# added in 24.03
__rte_eth_trace_tx_queue_count;
rte_eth_find_rss_algo;
+ rte_flow_async_update_resized;
rte_flow_calc_encap_hash;
+ rte_flow_template_table_resizable;
+ rte_flow_template_table_resize;
+ rte_flow_template_table_resize_complete;
};
INTERNAL {