diff options
| author | Gregory Etelson <[email protected]> | 2024-02-15 08:13:08 +0200 |
|---|---|---|
| committer | Ferruh Yigit <[email protected]> | 2024-02-15 12:55:21 +0100 |
| commit | 99231e480b69e2e722ae976c69e0c5dd4b37122a (patch) | |
| tree | 611b5d2b3fae4e204ed30cb1d0305e2f50fd597d /lib/ethdev | |
| parent | aa3e97fcb55d7b68fef864aa76078bdae375ad3d (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.h | 34 | ||||
| -rw-r--r-- | lib/ethdev/ethdev_trace_points.c | 9 | ||||
| -rw-r--r-- | lib/ethdev/rte_flow.c | 77 | ||||
| -rw-r--r-- | lib/ethdev/rte_flow.h | 119 | ||||
| -rw-r--r-- | lib/ethdev/rte_flow_driver.h | 15 | ||||
| -rw-r--r-- | lib/ethdev/version.map | 4 |
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 { |
