net/mlx5: add indirect count action
cover net/mlx5: add indirect count action
Add support of indirect action API for count action.
Michael Baum (5):
net/mlx5: support flow count action handle app/testpmd: remove indirect RSS action query app/testpmd: support indirect counter action query net/mlx5: fix flow age event triggering net/mlx5: use aging by counter when counter is existed
app/test-pmd/config.c | 152 +++++++------- doc/guides/nics/mlx5.rst | 13 +- doc/guides/rel_notes/release_21_05.rst | 1 + drivers/net/mlx5/mlx5.c | 8 +- drivers/net/mlx5/mlx5.h | 9 +- drivers/net/mlx5/mlx5_defs.h | 2 +- drivers/net/mlx5/mlx5_flow.c | 6 + drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 369 ++++++++++++++++++++++----------- drivers/net/mlx5/mlx5_flow_verbs.c | 2 +- 10 files changed, 360 insertions(+), 205 deletions(-)
Signature · 1 line
1.8.3.1
PATCH 1/5 net/mlx5: support flow count action handle
Existing API supports counter action to count traffic of a single flow. The user can share the count action among different flows using the shared flag and the same counter ID in the count action configuration.
Recent patch [1] introduced the indirect action API.
Using this API, an action can be created as indirect, unattached to any flow rule.
Multiple flows can then be created using the same indirect action. The new API also supports query operation of an indirect action.
The new API is more efficient because the driver gets it's own handler for the count action instead of managing a mapping between the user ID to the driver handle.
Support create, query and destroy indirect action operations for flow count action.
Application will use the indirect action query operation to query this count action.
In the meantime the old sharing mechanism (with the sharing flag) continues to be supported, and the user can choose the way he wants to share the counter.
The new indirect action API is only supported in DevX, so sharing counter action in Verbs can only be done through the old mechanism.
[1] https://mails.dpdk.org/archives/dev/2020-July/174110.html
--- doc/guides/nics/mlx5.rst | 13 +- doc/guides/rel_notes/release_21_05.rst | 1 + drivers/net/mlx5/mlx5.h | 7 +- drivers/net/mlx5/mlx5_defs.h | 2 +- drivers/net/mlx5/mlx5_flow.c | 6 + drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 222 ++++++++++++++++++++++----------- drivers/net/mlx5/mlx5_flow_verbs.c | 2 +- 8 files changed, 175 insertions(+), 81 deletions(-)
doc/guides/nics/mlx5.rst +9 -4
@@ -1692,10 +1692,15 @@ Supported hardware offloads | | | | | rdma-core 33 | | | | | | ConnectX-5 | +-----------------------+-----------------+-----------------+ - | Age | | DPDK 20.11 | | DPDK 20.11 | - | | | OFED 5.2 | | OFED 5.2 | - | | | rdma-core 32 | | rdma-core 32 | - | | | ConnectX-6 Dx| | ConnectX-6 Dx | + | Age | | DPDK 20.11 | | DPDK 20.11 | + | | | OFED 5.2 | | OFED 5.2 | + | | | rdma-core 32 | | rdma-core 32 | + | | | ConnectX-6 Dx | | ConnectX-6 Dx | + +-----------------------+-----------------+-----------------+ + | Count | | DPDK 21.05 | | DPDK 21.05 | + | | | OFED 4.6 | | OFED 4.6 | + | | | rdma-core 24 | | rdma-core 23 | + | | | ConnectX-5 | | ConnectX-5 | +-----------------------+-----------------+-----------------+ Notes for metadata
doc/guides/rel_notes/release_21_05.rst +1 -0
@@ -161,6 +161,7 @@ New Features Updated the Mellanox mlx5 driver with new features and improvements, including: * Added support for VXLAN and NVGRE encap as sample actions. + * Added support for flow COUNT action handle. * Support push VLAN on ingress traffic and pop VLAN on egress traffic in E-Switch mode. * Added support for ASO (Advanced Steering Operation) meter.
drivers/net/mlx5/mlx5.h +5 -2
@@ -291,7 +291,7 @@ struct mlx5_drop {#define MLX5_MAX_PENDING_QUERIES 4#define MLX5_CNT_CONTAINER_RESIZE 64#define MLX5_CNT_SHARED_OFFSET 0x80000000 -#define IS_SHARED_CNT (cnt) (!!((cnt) & MLX5_CNT_SHARED_OFFSET)) +#define IS_LEGACY_SHARED_CNT (cnt) (!!((cnt) & MLX5_CNT_SHARED_OFFSET))#define IS_BATCH_CNT (cnt) (((cnt) & (MLX5_CNT_SHARED_OFFSET - 1)) >= \ MLX5_CNT_BATCH_OFFSET)#define MLX5_CNT_SIZE (sizeof(struct mlx5_flow_counter))
@@ -353,7 +353,10 @@ struct flow_counter_stats {/* Shared counters information for counters. */ struct mlx5_flow_counter_shared { -uint32_t id;/**< User counter ID. */ +union { +uint32_t refcnt;/* Only for shared action management. */ +uint32_t id;/* User counter ID for legacy sharing. */ + }; };/* Shared counter configuration. */
drivers/net/mlx5/mlx5_defs.h +1 -1
@@ -193,7 +193,7 @@#define MLX5_HAIRPIN_JUMBO_LOG_SIZE (14 + 2)/* Maximum number of indirect actions supported by rte_flow */ -#define MLX5_MAX_INDIRECT_ACTIONS 2 +#define MLX5_MAX_INDIRECT_ACTIONS 3/* * Linux definition of static_assert is found in /usr/include/assert.h.
drivers/net/mlx5/mlx5_flow.c +6 -0
@@ -3540,6 +3540,12 @@ struct mlx5_translated_action_handle { translated[handle->index].conf = &shared_rss->origin;break ; +case MLX5_INDIRECT_ACTION_TYPE_COUNT : + translated[handle->index].type = + (enum rte_flow_action_type ) +MLX5_RTE_FLOW_ACTION_TYPE_COUNT ; + translated[handle->index].conf = (void *)(uintptr_t )idx; +break ;case MLX5_INDIRECT_ACTION_TYPE_AGE :if (priv->sh->flow_hit_aso_en) { translated[handle->index].type =
drivers/net/mlx5/mlx5_flow.h +2 -1
@@ -36,8 +36,8 @@ enum mlx5_rte_flow_action_type {MLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS ,MLX5_RTE_FLOW_ACTION_TYPE_TUNNEL_SET ,MLX5_RTE_FLOW_ACTION_TYPE_AGE , -MLX5_RTE_FLOW_ACTION_TYPE_JUMP ,MLX5_RTE_FLOW_ACTION_TYPE_COUNT , + MLX5_RTE_FLOW_ACTION_TYPE_JUMP, };#define MLX5_INDIRECT_ACTION_TYPE_OFFSET 30
@@ -45,6 +45,7 @@ enum mlx5_rte_flow_action_type {enum {MLX5_INDIRECT_ACTION_TYPE_RSS ,MLX5_INDIRECT_ACTION_TYPE_AGE , +MLX5_INDIRECT_ACTION_TYPE_COUNT , };/* Matches on selected register. */
drivers/net/mlx5/mlx5_flow_dv.c +150 -72
439 lines not on this page · raw message
drivers/net/mlx5/mlx5_flow_verbs.c +1 -1
@@ -357,7 +357,7 @@ struct ibv_spec_header {struct mlx5_flow_counter *cnt; cnt =flow_verbs_counter_get_by_idx (dev, counter, &pool); -if (IS_SHARED_CNT (counter) && +if (IS_LEGACY_SHARED_CNT (counter) &&mlx5_l3t_clear_entry (priv->sh->cnt_id_tbl, cnt->shared_info.id))return ;#if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42 )
Signature · 1 line
1.8.3.1
PATCH 2/5 app/testpmd: remove indirect RSS action query
In reply to Michael BaumThe port_action_handle_query function supports query operation for indirect RSS action.
No driver currently supports this operation, and this support is unnecessary.
Remove it.
--- app/test-pmd/config.c | 7 ------- 1 file changed, 7 deletions(-)
app/test-pmd/config.c +0 -7
@@ -1626,7 +1626,6 @@ struct rte_flow_action_handle *if (!pia)return -EINVAL ;switch (pia->type) { -case RTE_FLOW_ACTION_TYPE_RSS :case RTE_FLOW_ACTION_TYPE_AGE : data = &default_data;break ;
@@ -1638,12 +1637,6 @@ struct rte_flow_action_handle *if (rte_flow_action_handle_query (port_id, pia->handle, data, &error)) ret =port_flow_complain (&error);switch (pia->type) { -case RTE_FLOW_ACTION_TYPE_RSS : -if (!ret) -printf ("Shared RSS action:\n\trefs:%u\n" , - *((uint32_t *)data)); - data =NULL ; -break ;case RTE_FLOW_ACTION_TYPE_AGE :if (!ret) {struct rte_flow_query_age *resp = data;
Signature · 1 line
1.8.3.1
Re: [dpdk-dev] [PATCH 2/5] app/testpmd: remove indirect RSS action query
Hi Michael,
Quoted 44 lines
-----Original Message-----
From: dev <[email protected]> On Behalf Of Michael Baum
Sent: Monday, April 26, 2021 3:43 PM
Subject: [dpdk-dev] [PATCH 2/5] app/testpmd: remove indirect RSS action queryThe
port_action_handle_queryfunction supports query operation for indirect RSS action.No driver currently supports this operation, and this support is unnecessary.
Remove it.
Signed-off-by Michael Baum <[email protected]>Acked-by Matan Azrad <[email protected]>--- app/test-pmd/config.c | 7 ------- 1 file changed, 7 deletions(-)app/test-pmd/config.c index renamed from app/test-pmd/config.c +0
-0e189062..a9805cc 100644
app/test-pmd/config.c +0
-7@@ -1626,7 +1626,6 @@ struct rte_flow_action_handle *if (!pia)return -EINVAL ;switch (pia->type) { -case RTE_FLOW_ACTION_TYPE_RSS :case RTE_FLOW_ACTION_TYPE_AGE : data = &default_data;break ;@@ -1638,12 +1637,6 @@ struct rte_flow_action_handle *if (rte_flow_action_handle_query (port_id, pia->handle, data, &error)) ret =port_flow_complain (&error);switch (pia->type) { -case RTE_FLOW_ACTION_TYPE_RSS : -if (!ret) -printf ("Shared RSS action:\n\trefs:%u\n" , - *((uint32_t *)data)); - data =NULL ; -break ;case RTE_FLOW_ACTION_TYPE_AGE :if (!ret) {
Quoted 3 lines
struct
rte_flow_query_age*resp = data;
--
1.8.3.1
Thanks,
Ori
PATCH 3/5 app/testpmd: support indirect counter action query
In reply to Michael BaumCounter action query was implemented as part of flow query, but was not implemented as part of indirect action query.
This patch adds the required implementation.
--- app/test-pmd/config.c | 145 +++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 68 deletions(-)
app/test-pmd/config.c +77 -68
@@ -1618,90 +1618,99 @@ struct rte_flow_action_handle * {struct rte_flow_error error;struct port_indirect_action *pia; -uint64_t default_data; -void *data =NULL ; -int ret =0 ; +union { +struct rte_flow_query_count count; +struct rte_flow_query_age age; +struct rte_flow_action_conntrack ct; + } query; pia =action_get_by_id (port_id, id);if (!pia)return -EINVAL ;switch (pia->type) {case RTE_FLOW_ACTION_TYPE_AGE : - data = &default_data; +case RTE_FLOW_ACTION_TYPE_COUNT :break ;default : -printf ("Indirect action %u (type: %d) on port %u doesn't" -" support query\n" , id, pia->type, port_id); -return -1 ; +printf ("Indirect action %u (type: %d) on port %u doesn't support query\n" , + id, pia->type, port_id); +return -ENOTSUP ; } -if (rte_flow_action_handle_query (port_id, pia->handle, data, &error)) - ret =port_flow_complain (&error); +/* Poisoning to make sure PMDs update it in case of error. */ +memset (&error,0x55 ,sizeof (error)); +memset (&query,0 ,sizeof (query)); +if (rte_flow_action_handle_query (port_id, pia->handle, &query, &error)) +return port_flow_complain (&error);switch (pia->type) {case RTE_FLOW_ACTION_TYPE_AGE : -if (!ret) { -struct rte_flow_query_age *resp = data; - -printf ("AGE:\n" -" aged: %u\n" -" sec_since_last_hit_valid: %u\n" -" sec_since_last_hit: %" PRIu32"\n" , - resp->aged, - resp->sec_since_last_hit_valid, - resp->sec_since_last_hit); - } - data =NULL ; +printf ("Indirect AGE action:\n" +" aged: %u\n" +" sec_since_last_hit_valid: %u\n" +" sec_since_last_hit: %" PRIu32"\n" , + query.age.aged, + query.age.sec_since_last_hit_valid, + query.age.sec_since_last_hit); +break ; +case RTE_FLOW_ACTION_TYPE_COUNT : +printf ("Indirect COUNT action:\n" +" hits_set: %u\n" +" bytes_set: %u\n" +" hits: %" PRIu64"\n" +" bytes: %" PRIu64"\n" , + query.count.hits_set, + query.count.bytes_set, + query.count.hits, + query.count.bytes);break ;case RTE_FLOW_ACTION_TYPE_CONNTRACK : -if (!ret) { -struct rte_flow_action_conntrack *ct = data; - -printf ("Conntrack Context:\n" -" Peer: %u, Flow dir: %s, Enable: %u\n" -" Live: %u, SACK: %u, CACK: %u\n" -" Packet dir: %s, Liberal: %u, State: %u\n" -" Factor: %u, Retrans: %u, TCP flags: %u\n" -" Last Seq: %u, Last ACK: %u\n" -" Last Win: %u, Last End: %u\n" , - ct->peer_port, - ct->is_original_dir ?"Original" :"Reply" , - ct->enable, ct->live_connection, - ct->selective_ack, ct->challenge_ack_passed, - ct->last_direction ?"Original" :"Reply" , - ct->liberal_mode, ct->state, - ct->max_ack_window, ct->retransmission_limit, - ct->last_index, ct->last_seq, ct->last_ack, - ct->last_window, ct->last_end); -printf (" Original Dir:\n" -" scale: %u, fin: %u, ack seen: %u\n" -" unacked data: %u\n Sent end: %u," -" Reply end: %u, Max win: %u, Max ACK: %u\n" , - ct->original_dir.scale, - ct->original_dir.close_initiated, - ct->original_dir.last_ack_seen, - ct->original_dir.data_unacked, - ct->original_dir.sent_end, - ct->original_dir.reply_end, - ct->original_dir.max_win, - ct->original_dir.max_ack); -printf (" Reply Dir:\n" -" scale: %u, fin: %u, ack seen: %u\n" -" unacked data: %u\n Sent end: %u," -" Reply end: %u, Max win: %u, Max ACK: %u\n" , - ct->reply_dir.scale, - ct->reply_dir.close_initiated, - ct->reply_dir.last_ack_seen, - ct->reply_dir.data_unacked, - ct->reply_dir.sent_end, ct->reply_dir.reply_end, - ct->reply_dir.max_win, ct->reply_dir.max_ack); - } - data =NULL ; +printf ("Conntrack Context:\n" +" Peer: %u, Flow dir: %s, Enable: %u\n" +" Live: %u, SACK: %u, CACK: %u\n" +" Packet dir: %s, Liberal: %u, State: %u\n" +" Factor: %u, Retrans: %u, TCP flags: %u\n" +" Last Seq: %u, Last ACK: %u\n" +" Last Win: %u, Last End: %u\n" , + query.ct.peer_port, + query.ct.is_original_dir ?"Original" :"Reply" , + query.ct.enable, query.ct.live_connection, + query.ct.selective_ack, query.ct.challenge_ack_passed, + query.ct.last_direction ?"Original" :"Reply" , + query.ct.liberal_mode, query.ct.state, + query.ct.max_ack_window, query.ct.retransmission_limit, + query.ct.last_index, query.ct.last_seq, + query.ct.last_ack, query.ct.last_window, + query.ct.last_end); +printf (" Original Dir:\n" +" scale: %u, fin: %u, ack seen: %u\n" +" unacked data: %u\n Sent end: %u," +" Reply end: %u, Max win: %u, Max ACK: %u\n" , + query.ct.original_dir.scale, + query.ct.original_dir.close_initiated, + query.ct.original_dir.last_ack_seen, + query.ct.original_dir.data_unacked, + query.ct.original_dir.sent_end, + query.ct.original_dir.reply_end, + query.ct.original_dir.max_win, + query.ct.original_dir.max_ack); +printf (" Reply Dir:\n" +" scale: %u, fin: %u, ack seen: %u\n" +" unacked data: %u\n Sent end: %u," +" Reply end: %u, Max win: %u, Max ACK: %u\n" , + query.ct.reply_dir.scale, + query.ct.reply_dir.close_initiated, + query.ct.reply_dir.last_ack_seen, + query.ct.reply_dir.data_unacked, + query.ct.reply_dir.sent_end, + query.ct.reply_dir.reply_end, + query.ct.reply_dir.max_win, + query.ct.reply_dir.max_ack);break ;default : -printf ("Indirect action %u (type: %d) on port %u doesn't" -" support query\n" , id, pia->type, port_id); - ret =-1 ; +printf ("Indirect action %u (type: %d) on port %u doesn't support query\n" , + id, pia->type, port_id); +break ; } -return ret; +return 0 ; } static struct port_flow_tunnel *
Signature · 1 line
1.8.3.1
Re: [dpdk-dev] [PATCH 3/5] app/testpmd: support indirect counter action query
Hi Michael,
Quoted 198 lines
-----Original Message-----
From: dev <[email protected]> On Behalf Of Michael Baum
Sent: Monday, April 26, 2021 3:43 PM
To: [email protected]
Cc: Matan Azrad <[email protected]>; Raslan Darawsheh <[email protected]>; Slava Ovsiienko <[email protected]>
Subject: [dpdk-dev] [PATCH 3/5] app/testpmd: support indirect counter action queryCounter action query was implemented as part of flow query, but was not implemented as part of indirect action query.
This patch adds the required implementation.
Signed-off-by Michael Baum <[email protected]>Acked-by Matan Azrad <[email protected]>--- app/test-pmd/config.c | 145 +++++++++++++++++++++++++++--------------- -------- 1 file changed, 77 insertions(+), 68 deletions(-)app/test-pmd/config.c index renamed from app/test-pmd/config.c +0
-0a9805cc..bedbfcb 100644
app/test-pmd/config.c +77
-69@@ -1618,90 +1618,99 @@ struct rte_flow_action_handle * {struct rte_flow_error error;struct port_indirect_action *pia; -uint64_t default_data; -void *data =NULL ; -int ret =0 ; +union { +struct rte_flow_query_count count; +struct rte_flow_query_age age; +struct rte_flow_action_conntrack ct; + } query; pia =action_get_by_id (port_id, id);if (!pia)return -EINVAL ;switch (pia->type) {case RTE_FLOW_ACTION_TYPE_AGE : - data = &default_data; +case RTE_FLOW_ACTION_TYPE_COUNT :break ;default : -printf ("Indirect action %u (type: %d) on port %u doesn't" -" support query\n" , id, pia->type, port_id); -return -1 ; + printf("Indirect action %u (type: %d) on port %u doesn't support query\n", + id, pia->type, port_id); +return -ENOTSUP ; } -if (rte_flow_action_handle_query (port_id, pia->handle, data, &error)) - ret =port_flow_complain (&error); +/* Poisoning to make sure PMDs update it in case of error. */ +memset (&error,0x55 ,sizeof (error)); +memset (&query,0 ,sizeof (query)); +if (rte_flow_action_handle_query (port_id, pia->handle, &query, &error)) +return port_flow_complain (&error);switch (pia->type) {case RTE_FLOW_ACTION_TYPE_AGE : -if (!ret) { -struct rte_flow_query_age *resp = data; - -printf ("AGE:\n" -" aged: %u\n" -" sec_since_last_hit_valid: %u\n" -" sec_since_last_hit: %" PRIu32"\n" , - resp->aged, - resp->sec_since_last_hit_valid, - resp->sec_since_last_hit); - } - data =NULL ; +printf ("Indirect AGE action:\n" +" aged: %u\n" +" sec_since_last_hit_valid: %u\n" +" sec_since_last_hit: %" PRIu32"\n" , + query.age.aged, + query.age.sec_since_last_hit_valid, + query.age.sec_since_last_hit); +break ; +case RTE_FLOW_ACTION_TYPE_COUNT : +printf ("Indirect COUNT action:\n" +" hits_set: %u\n" +" bytes_set: %u\n" +" hits: %" PRIu64"\n" +" bytes: %" PRIu64"\n" , + query.count.hits_set, + query.count.bytes_set, + query.count.hits, + query.count.bytes);break ;case RTE_FLOW_ACTION_TYPE_CONNTRACK : -if (!ret) { -struct rte_flow_action_conntrack *ct = data; - -printf ("Conntrack Context:\n" -" Peer: %u, Flow dir: %s, Enable: %u\n" -" Live: %u, SACK: %u, CACK: %u\n" -" Packet dir: %s, Liberal: %u, State: %u\n" -" Factor: %u, Retrans: %u, TCP flags: %u\n" -" Last Seq: %u, Last ACK: %u\n" -" Last Win: %u, Last End: %u\n" , - ct->peer_port, - ct->is_original_dir ?"Original" :"Reply" , - ct->enable, ct->live_connection, - ct->selective_ack, ct->challenge_ack_passed, - ct->last_direction ?"Original" :"Reply" , - ct->liberal_mode, ct->state, - ct->max_ack_window, ct->retransmission_limit, - ct->last_index, ct->last_seq, ct->last_ack, - ct->last_window, ct->last_end); -printf (" Original Dir:\n" -" scale: %u, fin: %u, ack seen: %u\n" -" unacked data: %u\n Sent end: %u," -" Reply end: %u, Max win: %u, Max ACK: %u\n" , - ct->original_dir.scale, - ct->original_dir.close_initiated, - ct->original_dir.last_ack_seen, - ct->original_dir.data_unacked, - ct->original_dir.sent_end, - ct->original_dir.reply_end, - ct->original_dir.max_win, - ct->original_dir.max_ack); -printf (" Reply Dir:\n" -" scale: %u, fin: %u, ack seen: %u\n" -" unacked data: %u\n Sent end: %u," -" Reply end: %u, Max win: %u, Max ACK: %u\n" , - ct->reply_dir.scale, - ct->reply_dir.close_initiated, - ct->reply_dir.last_ack_seen, - ct->reply_dir.data_unacked, - ct->reply_dir.sent_end, ct->reply_dir.reply_end, - ct->reply_dir.max_win, ct->reply_dir.max_ack); - } - data =NULL ; +printf ("Conntrack Context:\n" +" Peer: %u, Flow dir: %s, Enable: %u\n" +" Live: %u, SACK: %u, CACK: %u\n" +" Packet dir: %s, Liberal: %u, State: %u\n" +" Factor: %u, Retrans: %u, TCP flags: %u\n" +" Last Seq: %u, Last ACK: %u\n" +" Last Win: %u, Last End: %u\n" , + query.ct.peer_port, + query.ct.is_original_dir ?"Original" :"Reply" , + query.ct.enable, query.ct.live_connection, + query.ct.selective_ack, query.ct.challenge_ack_passed, + query.ct.last_direction ?"Original" :"Reply" , + query.ct.liberal_mode, query.ct.state, + query.ct.max_ack_window, query.ct.retransmission_limit, + query.ct.last_index, query.ct.last_seq, + query.ct.last_ack, query.ct.last_window, + query.ct.last_end); +printf (" Original Dir:\n" +" scale: %u, fin: %u, ack seen: %u\n" +" unacked data: %u\n Sent end: %u," +" Reply end: %u, Max win: %u, Max ACK: %u\n" , + query.ct.original_dir.scale, + query.ct.original_dir.close_initiated, + query.ct.original_dir.last_ack_seen, + query.ct.original_dir.data_unacked, + query.ct.original_dir.sent_end, + query.ct.original_dir.reply_end, + query.ct.original_dir.max_win, + query.ct.original_dir.max_ack); +printf (" Reply Dir:\n" +" scale: %u, fin: %u, ack seen: %u\n" +" unacked data: %u\n Sent end: %u," +" Reply end: %u, Max win: %u, Max ACK: %u\n" , + query.ct.reply_dir.scale, + query.ct.reply_dir.close_initiated, + query.ct.reply_dir.last_ack_seen, + query.ct.reply_dir.data_unacked, + query.ct.reply_dir.sent_end, + query.ct.reply_dir.reply_end, + query.ct.reply_dir.max_win, + query.ct.reply_dir.max_ack);break ;default : -printf ("Indirect action %u (type: %d) on port %u doesn't" -" support query\n" , id, pia->type, port_id); - ret =-1 ; + printf("Indirect action %u (type: %d) on port %u doesn't support query\n", + id, pia->type, port_id); +break ; } - return ret; +return 0 ; } static struct port_flow_tunnel * --
Quoted 1 line
1.8.3.1
Thanks,
Ori
PATCH 4/5 net/mlx5: fix flow age event triggering
In reply to Michael BaumA FLOW_AGE event should be invoked when a new aged-out flow is detected by the PMD after the last user get-aged query calling.
The PMD manages 2 flags for this information and check them in order to decide if an event should be invoked:MLX5_AGE_EVENT_NEW - a new aged-out flow was detected. after the last check.MLX5_AGE_TRIGGER - get-aged query was called after the last aged-out flow.
The 2 flags were unset after the event invoking.
When the user calls get-aged query from the event callback, the TRIGGER flag was set inside the user callback and unset directly after the callback what may stop the event invoking forever.
Unset the TRIGGER flag before the event invoking in order to allow set it by the user callback.
--- drivers/net/mlx5/mlx5.c | 8 +++++--- drivers/net/mlx5/mlx5.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-)
drivers/net/mlx5/mlx5.c +5 -3
@@ -662,11 +662,13 @@ static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_dev_ctx_list = age_info = &sh->port[i].age_info;if (!MLX5_AGE_GET (age_info,MLX5_AGE_EVENT_NEW ))continue ; -if (MLX5_AGE_GET (age_info,MLX5_AGE_TRIGGER )) +MLX5_AGE_UNSET (age_info,MLX5_AGE_EVENT_NEW ); +if (MLX5_AGE_GET (age_info,MLX5_AGE_TRIGGER )) { +MLX5_AGE_UNSET (age_info,MLX5_AGE_TRIGGER );rte_eth_dev_callback_process (&rte_eth_devices[sh->port[i].devx_ih_port_id],RTE_ETH_EVENT_FLOW_AGED ,NULL ); - age_info->flags =0 ; + } } }
@@ -675,7 +677,7 @@ static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_dev_ctx_list =* * @param[in] sh * Pointer to mlx5_dev_ctx_shared object. -* @param[in] sh +* @param[in] config * Pointer to user dev config. */ static void
drivers/net/mlx5/mlx5.h +2 -0
@@ -563,6 +563,8 @@ struct mlx5_geneve_tlv_option_resource {#define MLX5_AGE_TRIGGER 2#define MLX5_AGE_SET (age_info,BIT ) \ ((age_info)->flags |= (1 << (BIT))) +#define MLX5_AGE_UNSET (age_info,BIT ) \ + ((age_info)->flags &= ~(1 << (BIT)))#define MLX5_AGE_GET (age_info,BIT ) \ ((age_info)->flags & (1 << (BIT)))#define GET_PORT_AGE_INFO (priv) \
Signature · 1 line
1.8.3.1
PATCH 5/5 net/mlx5: use aging by counter when counter is existed
In reply to Michael BaumThe driver support 2 mechanisms in order to support AGE action:
1. Aging by counter - HW counter will be configured to the flow traffic, the driver polls the counter values efficiently to detect flow timeout.
2. Aging by ASO flow hit bit - HW ASO flow-hit bit is allocated for the flow, the driver polls the bit efficiently to detect flow timeout.
ASO bit is only single bit resource while counter is 16 bytes, hence, it is better to use ASO instead of counter for aging.
When a non-shared COUNT action is also configured to the flow, the driver can use the same counter also for AGE action and no need to create more ASO action for it.
The current code always uses ASO when it is supported in the device, change it to reuse the non-shared counter if it exists in the flow.
--- drivers/net/mlx5/mlx5_flow_dv.c | 149 +++++++++++++++++++++++++++------------- 1 file changed, 102 insertions(+), 47 deletions(-)
drivers/net/mlx5/mlx5_flow_dv.c +102 -47
@@ -7143,6 +7143,12 @@ struct mlx5_hlist_entry *RTE_FLOW_ERROR_TYPE_UNSPECIFIED ,NULL , "Shared ASO age action is not supported for group 0"); +if (action_flags &MLX5_FLOW_ACTION_AGE ) +return rte_flow_error_set + (error,EINVAL , +RTE_FLOW_ERROR_TYPE_ACTION , +NULL , +"duplicate age actions set" ); action_flags |=MLX5_FLOW_ACTION_AGE ; ++actions_n;break ;
@@ -11163,6 +11169,47 @@ struct mlx5_cache_entry * }/** +* Prepares DV flow counter with aging configuration. +* Gets it by index when exists, creates a new one when doesn't. +* +* @param[in] dev +* Pointer to rte_eth_dev structure. +* @param[in] dev_flow +* Pointer to the mlx5_flow. +* @param[in, out] flow +* Pointer to the sub flow. +* @param[in] count +* Pointer to the counter action configuration. +* @param[in] age +* Pointer to the aging action configuration. +* @param[out] error +* Pointer to the error structure. +* +* @return +* Pointer to the counter, NULL otherwise. +*/ +static struct mlx5_flow_counter * +flow_dv_prepare_counter (struct rte_eth_dev *dev, +struct mlx5_flow *dev_flow, +struct rte_flow *flow, +const struct rte_flow_action_count *count, +const struct rte_flow_action_age *age, +struct rte_flow_error *error) +{ +if (!flow->counter) { + flow->counter =flow_dv_translate_create_counter (dev, dev_flow, + count, age); +if (!flow->counter) { +rte_flow_error_set (error, rte_errno, +RTE_FLOW_ERROR_TYPE_ACTION ,NULL , +"cannot create counter object." ); +return NULL ; + } + } +return flow_dv_counter_get_by_idx (dev, flow->counter,NULL ); +} + +/** * Fill the flow with DV spec, lock free * (mutex should be acquired by caller). *
@@ -11215,7 +11262,7 @@ struct mlx5_cache_entry * } mhdr_dummy;struct mlx5_flow_dv_modify_hdr_resource *mhdr_res = &mhdr_dummy.res;const struct rte_flow_action_count *count =NULL ; -const struct rte_flow_action_age *age =NULL ; +const struct rte_flow_action_age *non_shared_age =NULL ;union flow_dv_attr flow_attr = { .attr =0 };uint32_t tag_be;union mlx5_flow_tbl_key tbl_key;
@@ -11230,6 +11277,7 @@ struct mlx5_cache_entry *const struct rte_flow_action_sample *sample =NULL ;struct mlx5_flow_sub_actions_list *sample_act;uint32_t sample_act_pos =UINT32_MAX ; +uint32_t age_act_pos =UINT32_MAX ;uint32_t num_of_dest =0 ;int tmp_actions_n =0 ;uint32_t table;
@@ -11452,7 +11500,12 @@ struct mlx5_cache_entry * age_act =flow_aso_age_get_by_idx (dev, flow->age);__atomic_fetch_add (&age_act->refcnt,1 , __ATOMIC_RELAXED); - dev_flow->dv.actions[actions_n++] = age_act->dr_action; + age_act_pos = actions_n++; + action_flags |=MLX5_FLOW_ACTION_AGE ; +break ; +case RTE_FLOW_ACTION_TYPE_AGE : + non_shared_age = action->conf; + age_act_pos = actions_n++; action_flags |=MLX5_FLOW_ACTION_AGE ;break ;case MLX5_RTE_FLOW_ACTION_TYPE_COUNT :
@@ -11464,31 +11517,6 @@ struct mlx5_cache_entry */* Save information first, will apply later. */ action_flags |=MLX5_FLOW_ACTION_COUNT ;break ; -case RTE_FLOW_ACTION_TYPE_AGE : -if (priv->sh->flow_hit_aso_en && attr->group) { -/* -* Create one shared age action, to be used -* by all sub-flows. -*/ -if (!flow->age) { - flow->age = -flow_dv_translate_create_aso_age - (dev, action->conf, - error); -if (!flow->age) -return rte_flow_error_set - (error, rte_errno, -RTE_FLOW_ERROR_TYPE_ACTION , -NULL , -"can't create ASO age action" ); - } - dev_flow->dv.actions[actions_n++] = - (flow_aso_age_get_by_idx - (dev, flow->age))->dr_action; - action_flags |=MLX5_FLOW_ACTION_AGE ; -break ; - } -/* Fall-through */ case RTE_FLOW_ACTION_TYPE_COUNT :if (!dev_conf->devx) {return rte_flow_error_set
@@ -11498,10 +11526,7 @@ struct mlx5_cache_entry * "count action not supported"); }/* Save information first, will apply later. */ -if (actions->type ==RTE_FLOW_ACTION_TYPE_COUNT ) - count = action->conf; -else - age = action->conf; + count = action->conf; action_flags |=MLX5_FLOW_ACTION_COUNT ;break ;case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN :
@@ -11801,27 +11826,57 @@ struct mlx5_cache_entry * dev_flow->dv.actions[modify_action_position] = handle->dvh.modify_hdr->action; } +/* +* Handle AGE and COUNT action by single HW counter +* when they are not shared. +*/ +if (action_flags &MLX5_FLOW_ACTION_AGE ) { +if ((non_shared_age && + count && !count->shared) || + !(priv->sh->flow_hit_aso_en && + attr->group)) { +/* Creates age by counters. */ + cnt_act =flow_dv_prepare_counter + (dev, dev_flow, + flow, count, + non_shared_age, + error); +if (!cnt_act) +return -rte_errno; + dev_flow->dv.actions[age_act_pos] = + cnt_act->action; +break ; + } +if (!flow->age && non_shared_age) { + flow->age = +flow_dv_translate_create_aso_age + (dev, + non_shared_age, + error); +if (!flow->age) +return rte_flow_error_set + (error, rte_errno, +RTE_FLOW_ERROR_TYPE_ACTION , +NULL , +"can't create ASO age action" ); + } + age_act =flow_aso_age_get_by_idx (dev, + flow->age); + dev_flow->dv.actions[age_act_pos] = + age_act->dr_action; + }if (action_flags &MLX5_FLOW_ACTION_COUNT ) {/* * Create one count action, to be used * by all sub-flows. */ -if (!flow->counter) { - flow->counter = -flow_dv_translate_create_counter - (dev, dev_flow, count, - age); -if (!flow->counter) -return rte_flow_error_set - (error, rte_errno, -RTE_FLOW_ERROR_TYPE_ACTION , -NULL ,"cannot create counter" -" object." ); - } - dev_flow->dv.actions[actions_n] = - (flow_dv_counter_get_by_idx (dev, - flow->counter,NULL ))->action; - actions_n++; + cnt_act =flow_dv_prepare_counter (dev, dev_flow, + flow, count, +NULL , error); +if (!cnt_act) +return -rte_errno; + dev_flow->dv.actions[actions_n++] = + cnt_act->action; }default :break ;
Signature · 1 line
1.8.3.1
v2 cover Add support of indirect action API for count action.
In reply to Michael Baumv1: http://patches.dpdk.org/project/dpdk/patch/[email protected]/
V2: patch rebase
Michael Baum (5):
net/mlx5: support flow count action handle app/testpmd: remove indirect RSS action query app/testpmd: support indirect counter action query net/mlx5: fix flow age event triggering net/mlx5: use aging by counter when counter is existed
app/test-pmd/config.c | 152 +++++----- doc/guides/nics/mlx5.rst | 13 +- doc/guides/rel_notes/release_21_05.rst | 1 + drivers/net/mlx5/mlx5.c | 8 +- drivers/net/mlx5/mlx5.h | 9 +- drivers/net/mlx5/mlx5_defs.h | 2 +- drivers/net/mlx5/mlx5_flow.c | 6 + drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 369 +++++++++++++++++-------- drivers/net/mlx5/mlx5_flow_verbs.c | 2 +- 10 files changed, 360 insertions(+), 205 deletions(-)
Signature · 1 line
2.18.1
PATCH v2 1/5 net/mlx5: support flow count action handle
From: Michael Baum <[email protected]>
Existing API supports counter action to count traffic of a single flow. The user can share the count action among different flows using the shared flag and the same counter ID in the count action configuration.
Recent patch [1] introduced the indirect action API.
Using this API, an action can be created as indirect, unattached to any flow rule.
Multiple flows can then be created using the same indirect action. The new API also supports query operation of an indirect action.
The new API is more efficient because the driver gets it's own handler for the count action instead of managing a mapping between the user ID to the driver handle.
Support create, query and destroy indirect action operations for flow count action.
Application will use the indirect action query operation to query this count action.
In the meantime the old sharing mechanism (with the sharing flag) continues to be supported, and the user can choose the way he wants to share the counter.
The new indirect action API is only supported in DevX, so sharing counter action in Verbs can only be done through the old mechanism.
[1] https://mails.dpdk.org/archives/dev/2020-July/174110.html
--- doc/guides/nics/mlx5.rst | 13 +- doc/guides/rel_notes/release_21_05.rst | 1 + drivers/net/mlx5/mlx5.h | 7 +- drivers/net/mlx5/mlx5_defs.h | 2 +- drivers/net/mlx5/mlx5_flow.c | 6 + drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 222 +++++++++++++++++-------- drivers/net/mlx5/mlx5_flow_verbs.c | 2 +- 8 files changed, 175 insertions(+), 81 deletions(-)
doc/guides/nics/mlx5.rst +9 -4
@@ -1692,10 +1692,15 @@ Supported hardware offloads | | | | | rdma-core 33 | | | | | | ConnectX-5 | +-----------------------+-----------------+-----------------+ - | Age | | DPDK 20.11 | | DPDK 20.11 | - | | | OFED 5.2 | | OFED 5.2 | - | | | rdma-core 32 | | rdma-core 32 | - | | | ConnectX-6 Dx| | ConnectX-6 Dx | + | Age | | DPDK 20.11 | | DPDK 20.11 | + | | | OFED 5.2 | | OFED 5.2 | + | | | rdma-core 32 | | rdma-core 32 | + | | | ConnectX-6 Dx | | ConnectX-6 Dx | + +-----------------------+-----------------+-----------------+ + | Count | | DPDK 21.05 | | DPDK 21.05 | + | | | OFED 4.6 | | OFED 4.6 | + | | | rdma-core 24 | | rdma-core 23 | + | | | ConnectX-5 | | ConnectX-5 | +-----------------------+-----------------+-----------------+ Notes for metadata
doc/guides/rel_notes/release_21_05.rst +1 -0
@@ -161,6 +161,7 @@ New Features Updated the Mellanox mlx5 driver with new features and improvements, including: * Added support for VXLAN and NVGRE encap as sample actions. + * Added support for flow COUNT action handle. * Support push VLAN on ingress traffic and pop VLAN on egress traffic in E-Switch mode. * Added support for pre-defined meter policy API. * Added support for ASO (Advanced Steering Operation) meter.
drivers/net/mlx5/mlx5.h +5 -2
@@ -291,7 +291,7 @@ struct mlx5_drop {#define MLX5_MAX_PENDING_QUERIES 4#define MLX5_CNT_CONTAINER_RESIZE 64#define MLX5_CNT_SHARED_OFFSET 0x80000000 -#define IS_SHARED_CNT (cnt) (!!((cnt) & MLX5_CNT_SHARED_OFFSET)) +#define IS_LEGACY_SHARED_CNT (cnt) (!!((cnt) & MLX5_CNT_SHARED_OFFSET))#define IS_BATCH_CNT (cnt) (((cnt) & (MLX5_CNT_SHARED_OFFSET - 1)) >= \ MLX5_CNT_BATCH_OFFSET)#define MLX5_CNT_SIZE (sizeof(struct mlx5_flow_counter))
@@ -353,7 +353,10 @@ struct flow_counter_stats {/* Shared counters information for counters. */ struct mlx5_flow_counter_shared { -uint32_t id;/**< User counter ID. */ +union { +uint32_t refcnt;/* Only for shared action management. */ +uint32_t id;/* User counter ID for legacy sharing. */ + }; };/* Shared counter configuration. */
drivers/net/mlx5/mlx5_defs.h +1 -1
@@ -193,7 +193,7 @@#define MLX5_HAIRPIN_JUMBO_LOG_SIZE (14 + 2)/* Maximum number of indirect actions supported by rte_flow */ -#define MLX5_MAX_INDIRECT_ACTIONS 2 +#define MLX5_MAX_INDIRECT_ACTIONS 3/* * Linux definition of static_assert is found in /usr/include/assert.h.
drivers/net/mlx5/mlx5_flow.c +6 -0
@@ -3540,6 +3540,12 @@ flow_action_handles_translate(struct rte_eth_dev *dev, translated[handle->index].conf = &shared_rss->origin;break ; +case MLX5_INDIRECT_ACTION_TYPE_COUNT : + translated[handle->index].type = + (enum rte_flow_action_type ) +MLX5_RTE_FLOW_ACTION_TYPE_COUNT ; + translated[handle->index].conf = (void *)(uintptr_t )idx; +break ;case MLX5_INDIRECT_ACTION_TYPE_AGE :if (priv->sh->flow_hit_aso_en) { translated[handle->index].type =
drivers/net/mlx5/mlx5_flow.h +2 -1
@@ -36,8 +36,8 @@ enum mlx5_rte_flow_action_type {MLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS ,MLX5_RTE_FLOW_ACTION_TYPE_TUNNEL_SET ,MLX5_RTE_FLOW_ACTION_TYPE_AGE , -MLX5_RTE_FLOW_ACTION_TYPE_JUMP ,MLX5_RTE_FLOW_ACTION_TYPE_COUNT , + MLX5_RTE_FLOW_ACTION_TYPE_JUMP, };#define MLX5_INDIRECT_ACTION_TYPE_OFFSET 30
@@ -45,6 +45,7 @@ enum mlx5_rte_flow_action_type {enum {MLX5_INDIRECT_ACTION_TYPE_RSS ,MLX5_INDIRECT_ACTION_TYPE_AGE , +MLX5_INDIRECT_ACTION_TYPE_COUNT , };/* Matches on selected register. */
drivers/net/mlx5/mlx5_flow_dv.c +150 -72
440 lines not on this page · raw message
drivers/net/mlx5/mlx5_flow_verbs.c +1 -1
@@ -357,7 +357,7 @@ flow_verbs_counter_release(struct rte_eth_dev *dev, uint32_t counter)struct mlx5_flow_counter *cnt; cnt =flow_verbs_counter_get_by_idx (dev, counter, &pool); -if (IS_SHARED_CNT (counter) && +if (IS_LEGACY_SHARED_CNT (counter) &&mlx5_l3t_clear_entry (priv->sh->cnt_id_tbl, cnt->shared_info.id))return ;#if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42 )
Signature · 1 line
2.18.1
Re: [dpdk-dev] [PATCH v2 1/5] net/mlx5: support flow count action handle
Quoted 19 lines · Viacheslav Ovsiienko
From: Michael Baum <[email protected]>
Existing API supports counter action to count traffic of a single flow. The user can share the count action among different flows using the shared flag and the same counter ID in the count action configuration.
Recent patch [1] introduced the indirect action API.
Using this API, an action can be created as indirect, unattached to any flow rule.
Multiple flows can then be created using the same indirect action. The new API also supports query operation of an indirect action.The new API is more efficient because the driver gets it's own handler for the count action instead of managing a mapping between the user ID to the driver handle.
Support create, query and destroy indirect action operations for flow count action.
Quoted 9 lines
Application will use the indirect action query operation to query this count action.
In the meantime the old sharing mechanism (with the sharing flag) continues to be supported, and the user can choose the way he wants to share the counter.
The new indirect action API is only supported in DevX, so sharing counter action in Verbs can only be done through the old mechanism.
There is already a deprecation note to remove the 'shared' flag from counter action [2] in favor of 'shared actions'.
Shared action become "indirect actions" [3] which this patch implements
Is it a good time to remove the old sharing mechanism from driver since touching on it?
[2]
https://git.dpdk.org/dpdk/tree/doc/guides/rel_notes/deprecation.rst?h=v21.05-rc1#n95
[3]
https://git.dpdk.org/dpdk/commit/?h=v21.05-rc1&id=4b61b8774be9
Quoted 4 lines
[1] https://mails.dpdk.org/archives/dev/2020-July/174110.html
Signed-off-by Michael Baum <[email protected]>Acked-by Matan Azrad <[email protected]>
<...>
Re: [dpdk-dev] [PATCH v2 1/5] net/mlx5: support flow count action handle
Hi, Ferruh
Quoted 40 lines
-----Original Message-----
From: Ferruh Yigit <[email protected]>
Sent: Friday, April 30, 2021 11:35
To: Slava Ovsiienko <[email protected]>; [email protected]; Andrew Rybchenko <[email protected]>
Cc: Raslan Darawsheh <[email protected]>; Matan Azrad <[email protected]>; Michael Baum <[email protected]>; NBU- Contact-Thomas Monjalon <[email protected]>
Subject: Re: [PATCH v2 1/5] net/mlx5: support flow count action handleQuoted 19 lines · Viacheslav Ovsiienko
From: Michael Baum <[email protected]>
Existing API supports counter action to count traffic of a single flow. The user can share the count action among different flows using the shared flag and the same counter ID in the count action configuration.
Recent patch [1] introduced the indirect action API. Using this API, an action can be created as indirect, unattached to any flow rule.
Multiple flows can then be created using the same indirect action. The new API also supports query operation of an indirect action.The new API is more efficient because the driver gets it's own handler for the count action instead of managing a mapping between the user ID to the driver handle.
Support create, query and destroy indirect action operations for flow count action.
Quoted 9 lines
Application will use the indirect action query operation to query this count action.
In the meantime the old sharing mechanism (with the sharing flag) continues to be supported, and the user can choose the way he wants to share the counter.
The new indirect action API is only supported in DevX, so sharing counter action in Verbs can only be done through the old mechanism.
Quoted 7 lines
There is already a deprecation note to remove the 'shared' flag from counter action [2] in favor of 'shared actions'.
Shared action become "indirect actions" [3] which this patch implements
Is it a good time to remove the old sharing mechanism from driver since touching on it?
As I can see:
- it is planned to 21.11 as deprecation note says
- now there Is no support for new "indirect actions" with Verbs (not sure
we will provide), so shared counters API might be still useful
- our CI did not migrate to the new counter approach yet (even DPDK patch is not merged yet 😊)
- hence, l would prefer keep shared counter support (by id and flag) in 21.05 (and very likely in 21.08), just to maintain maximal backward compatibility as long
as possible
With best regards,
Slava
Quoted 16 lines
[2]
https://git.dpdk.org/dpdk/tree/doc/guides/rel_notes/deprecation.rst?h=v2
1.05-rc1#n95[3]
https://git.dpdk.org/dpdk/commit/?h=v21.05-rc1&id=4b61b8774be9Quoted 4 lines
[1] https://mails.dpdk.org/archives/dev/2020-July/174110.html
Signed-off-by Michael Baum <[email protected]>Acked-by Matan Azrad <[email protected]><...>
Re: [dpdk-dev] [PATCH v2 1/5] net/mlx5: support flow count action handle
Quoted 45 lines · Slava Ovsiienko
Hi, Ferruh
Quoted 43 lines
-----Original Message-----
From: Ferruh Yigit <[email protected]>
Sent: Friday, April 30, 2021 11:35
To: Slava Ovsiienko <[email protected]>; [email protected]; Andrew Rybchenko <[email protected]>
Cc: Raslan Darawsheh <[email protected]>; Matan Azrad <[email protected]>; Michael Baum <[email protected]>; NBU- Contact-Thomas Monjalon <[email protected]>
Subject: Re: [PATCH v2 1/5] net/mlx5: support flow count action handleQuoted 19 lines · Viacheslav Ovsiienko
From: Michael Baum <[email protected]>
Existing API supports counter action to count traffic of a single flow. The user can share the count action among different flows using the shared flag and the same counter ID in the count action configuration.
Recent patch [1] introduced the indirect action API. Using this API, an action can be created as indirect, unattached to any flow rule.
Multiple flows can then be created using the same indirect action. The new API also supports query operation of an indirect action.The new API is more efficient because the driver gets it's own handler for the count action instead of managing a mapping between the user ID to the driver handle.
Support create, query and destroy indirect action operations for flow count action.
Quoted 9 lines
Application will use the indirect action query operation to query this count action.
In the meantime the old sharing mechanism (with the sharing flag) continues to be supported, and the user can choose the way he wants to share the counter.
The new indirect action API is only supported in DevX, so sharing counter action in Verbs can only be done through the old mechanism.There is already a deprecation note to remove the 'shared' flag from counter action [2] in favor of 'shared actions'.
Quoted 7 lines
Quoted 4 lines
Shared action become "indirect actions" [3] which this patch implements
Is it a good time to remove the old sharing mechanism from driver since touching on it?
As I can see:
- it is planned to 21.11 as deprecation note says
Yes, deprecation is for 21.11, but I though it might be easier for you to remove it now while it is under rework, but I can see you prefer to keep it.
Quoted 7 lines
- now there Is no support for new "indirect actions" with Verbs (not sure
we will provide), so shared counters API might be still useful
- our CI did not migrate to the new counter approach yet (even DPDK patch is not merged yet 😊)
- hence, l would prefer keep shared counter support (by id and flag) in 21.05 (and very likely in 21.08), just to maintain maximal backward compatibility as long
as possible
OK
Quoted 19 lines
With best regards,
SlavaQuoted 16 lines
[2]
https://git.dpdk.org/dpdk/tree/doc/guides/rel_notes/deprecation.rst?h=v2
1.05-rc1#n95[3]
https://git.dpdk.org/dpdk/commit/?h=v21.05-rc1&id=4b61b8774be9Quoted 4 lines
[1] https://mails.dpdk.org/archives/dev/2020-July/174110.html
Signed-off-by Michael Baum <[email protected]>Acked-by Matan Azrad <[email protected]><...>
PATCH v2 2/5 app/testpmd: remove indirect RSS action query
In reply to Viacheslav OvsiienkoFrom: Michael Baum <[email protected]>
The port_action_handle_query function supports query operation for indirect RSS action.
No driver currently supports this operation, and this support is unnecessary.
Remove it.
--- app/test-pmd/config.c | 7 ------- 1 file changed, 7 deletions(-)
app/test-pmd/config.c +0 -7
@@ -1626,7 +1626,6 @@ port_action_handle_query(portid_t port_id, uint32_t id)if (!pia)return -EINVAL ;switch (pia->type) { -case RTE_FLOW_ACTION_TYPE_RSS :case RTE_FLOW_ACTION_TYPE_AGE : data = &default_data;break ;
@@ -1638,12 +1637,6 @@ port_action_handle_query(portid_t port_id, uint32_t id)if (rte_flow_action_handle_query (port_id, pia->handle, data, &error)) ret =port_flow_complain (&error);switch (pia->type) { -case RTE_FLOW_ACTION_TYPE_RSS : -if (!ret) -printf ("Shared RSS action:\n\trefs:%u\n" , - *((uint32_t *)data)); - data =NULL ; -break ;case RTE_FLOW_ACTION_TYPE_AGE :if (!ret) {struct rte_flow_query_age *resp = data;
Signature · 1 line
2.18.1
PATCH v2 3/5 app/testpmd: support indirect counter action query
In reply to Viacheslav OvsiienkoFrom: Michael Baum <[email protected]>
Counter action query was implemented as part of flow query, but was not implemented as part of indirect action query.
This patch adds the required implementation.
--- app/test-pmd/config.c | 145 ++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 68 deletions(-)
app/test-pmd/config.c +77 -68
@@ -1618,90 +1618,99 @@ port_action_handle_query(portid_t port_id, uint32_t id) {struct rte_flow_error error;struct port_indirect_action *pia; -uint64_t default_data; -void *data =NULL ; -int ret =0 ; +union { +struct rte_flow_query_count count; +struct rte_flow_query_age age; +struct rte_flow_action_conntrack ct; + } query; pia =action_get_by_id (port_id, id);if (!pia)return -EINVAL ;switch (pia->type) {case RTE_FLOW_ACTION_TYPE_AGE : - data = &default_data; +case RTE_FLOW_ACTION_TYPE_COUNT :break ;default : -printf ("Indirect action %u (type: %d) on port %u doesn't" -" support query\n" , id, pia->type, port_id); -return -1 ; +printf ("Indirect action %u (type: %d) on port %u doesn't support query\n" , + id, pia->type, port_id); +return -ENOTSUP ; } -if (rte_flow_action_handle_query (port_id, pia->handle, data, &error)) - ret =port_flow_complain (&error); +/* Poisoning to make sure PMDs update it in case of error. */ +memset (&error,0x55 ,sizeof (error)); +memset (&query,0 ,sizeof (query)); +if (rte_flow_action_handle_query (port_id, pia->handle, &query, &error)) +return port_flow_complain (&error);switch (pia->type) {case RTE_FLOW_ACTION_TYPE_AGE : -if (!ret) { -struct rte_flow_query_age *resp = data; - -printf ("AGE:\n" -" aged: %u\n" -" sec_since_last_hit_valid: %u\n" -" sec_since_last_hit: %" PRIu32"\n" , - resp->aged, - resp->sec_since_last_hit_valid, - resp->sec_since_last_hit); - } - data =NULL ; +printf ("Indirect AGE action:\n" +" aged: %u\n" +" sec_since_last_hit_valid: %u\n" +" sec_since_last_hit: %" PRIu32"\n" , + query.age.aged, + query.age.sec_since_last_hit_valid, + query.age.sec_since_last_hit); +break ; +case RTE_FLOW_ACTION_TYPE_COUNT : +printf ("Indirect COUNT action:\n" +" hits_set: %u\n" +" bytes_set: %u\n" +" hits: %" PRIu64"\n" +" bytes: %" PRIu64"\n" , + query.count.hits_set, + query.count.bytes_set, + query.count.hits, + query.count.bytes);break ;case RTE_FLOW_ACTION_TYPE_CONNTRACK : -if (!ret) { -struct rte_flow_action_conntrack *ct = data; - -printf ("Conntrack Context:\n" -" Peer: %u, Flow dir: %s, Enable: %u\n" -" Live: %u, SACK: %u, CACK: %u\n" -" Packet dir: %s, Liberal: %u, State: %u\n" -" Factor: %u, Retrans: %u, TCP flags: %u\n" -" Last Seq: %u, Last ACK: %u\n" -" Last Win: %u, Last End: %u\n" , - ct->peer_port, - ct->is_original_dir ?"Original" :"Reply" , - ct->enable, ct->live_connection, - ct->selective_ack, ct->challenge_ack_passed, - ct->last_direction ?"Original" :"Reply" , - ct->liberal_mode, ct->state, - ct->max_ack_window, ct->retransmission_limit, - ct->last_index, ct->last_seq, ct->last_ack, - ct->last_window, ct->last_end); -printf (" Original Dir:\n" -" scale: %u, fin: %u, ack seen: %u\n" -" unacked data: %u\n Sent end: %u," -" Reply end: %u, Max win: %u, Max ACK: %u\n" , - ct->original_dir.scale, - ct->original_dir.close_initiated, - ct->original_dir.last_ack_seen, - ct->original_dir.data_unacked, - ct->original_dir.sent_end, - ct->original_dir.reply_end, - ct->original_dir.max_win, - ct->original_dir.max_ack); -printf (" Reply Dir:\n" -" scale: %u, fin: %u, ack seen: %u\n" -" unacked data: %u\n Sent end: %u," -" Reply end: %u, Max win: %u, Max ACK: %u\n" , - ct->reply_dir.scale, - ct->reply_dir.close_initiated, - ct->reply_dir.last_ack_seen, - ct->reply_dir.data_unacked, - ct->reply_dir.sent_end, ct->reply_dir.reply_end, - ct->reply_dir.max_win, ct->reply_dir.max_ack); - } - data =NULL ; +printf ("Conntrack Context:\n" +" Peer: %u, Flow dir: %s, Enable: %u\n" +" Live: %u, SACK: %u, CACK: %u\n" +" Packet dir: %s, Liberal: %u, State: %u\n" +" Factor: %u, Retrans: %u, TCP flags: %u\n" +" Last Seq: %u, Last ACK: %u\n" +" Last Win: %u, Last End: %u\n" , + query.ct.peer_port, + query.ct.is_original_dir ?"Original" :"Reply" , + query.ct.enable, query.ct.live_connection, + query.ct.selective_ack, query.ct.challenge_ack_passed, + query.ct.last_direction ?"Original" :"Reply" , + query.ct.liberal_mode, query.ct.state, + query.ct.max_ack_window, query.ct.retransmission_limit, + query.ct.last_index, query.ct.last_seq, + query.ct.last_ack, query.ct.last_window, + query.ct.last_end); +printf (" Original Dir:\n" +" scale: %u, fin: %u, ack seen: %u\n" +" unacked data: %u\n Sent end: %u," +" Reply end: %u, Max win: %u, Max ACK: %u\n" , + query.ct.original_dir.scale, + query.ct.original_dir.close_initiated, + query.ct.original_dir.last_ack_seen, + query.ct.original_dir.data_unacked, + query.ct.original_dir.sent_end, + query.ct.original_dir.reply_end, + query.ct.original_dir.max_win, + query.ct.original_dir.max_ack); +printf (" Reply Dir:\n" +" scale: %u, fin: %u, ack seen: %u\n" +" unacked data: %u\n Sent end: %u," +" Reply end: %u, Max win: %u, Max ACK: %u\n" , + query.ct.reply_dir.scale, + query.ct.reply_dir.close_initiated, + query.ct.reply_dir.last_ack_seen, + query.ct.reply_dir.data_unacked, + query.ct.reply_dir.sent_end, + query.ct.reply_dir.reply_end, + query.ct.reply_dir.max_win, + query.ct.reply_dir.max_ack);break ;default : -printf ("Indirect action %u (type: %d) on port %u doesn't" -" support query\n" , id, pia->type, port_id); - ret =-1 ; +printf ("Indirect action %u (type: %d) on port %u doesn't support query\n" , + id, pia->type, port_id); +break ; } -return ret; +return 0 ; } static struct port_flow_tunnel *
Signature · 1 line
2.18.1
PATCH v2 4/5 net/mlx5: fix flow age event triggering
In reply to Viacheslav OvsiienkoFrom: Michael Baum <[email protected]>
A FLOW_AGE event should be invoked when a new aged-out flow is detected by the PMD after the last user get-aged query calling.
The PMD manages 2 flags for this information and check them in order to decide if an event should be invoked:MLX5_AGE_EVENT_NEW - a new aged-out flow was detected. after the last check.MLX5_AGE_TRIGGER - get-aged query was called after the last aged-out flow.
The 2 flags were unset after the event invoking.
When the user calls get-aged query from the event callback, the TRIGGER flag was set inside the user callback and unset directly after the callback what may stop the event invoking forever.
Unset the TRIGGER flag before the event invoking in order to allow set it by the user callback.
--- drivers/net/mlx5/mlx5.c | 8 +++++--- drivers/net/mlx5/mlx5.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-)
drivers/net/mlx5/mlx5.c +5 -3
@@ -662,11 +662,13 @@ mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh) age_info = &sh->port[i].age_info;if (!MLX5_AGE_GET (age_info,MLX5_AGE_EVENT_NEW ))continue ; -if (MLX5_AGE_GET (age_info,MLX5_AGE_TRIGGER )) +MLX5_AGE_UNSET (age_info,MLX5_AGE_EVENT_NEW ); +if (MLX5_AGE_GET (age_info,MLX5_AGE_TRIGGER )) { +MLX5_AGE_UNSET (age_info,MLX5_AGE_TRIGGER );rte_eth_dev_callback_process (&rte_eth_devices[sh->port[i].devx_ih_port_id],RTE_ETH_EVENT_FLOW_AGED ,NULL ); - age_info->flags =0 ; + } } }
@@ -675,7 +677,7 @@ mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh)* * @param[in] sh * Pointer to mlx5_dev_ctx_shared object. -* @param[in] sh +* @param[in] config * Pointer to user dev config. */ static void
drivers/net/mlx5/mlx5.h +2 -0
@@ -563,6 +563,8 @@ struct mlx5_geneve_tlv_option_resource {#define MLX5_AGE_TRIGGER 2#define MLX5_AGE_SET (age_info,BIT ) \ ((age_info)->flags |= (1 << (BIT))) +#define MLX5_AGE_UNSET (age_info,BIT ) \ + ((age_info)->flags &= ~(1 << (BIT)))#define MLX5_AGE_GET (age_info,BIT ) \ ((age_info)->flags & (1 << (BIT)))#define GET_PORT_AGE_INFO (priv) \
Signature · 1 line
2.18.1
PATCH v2 5/5 net/mlx5: use aging by counter when counter is existed
In reply to Viacheslav OvsiienkoFrom: Michael Baum <[email protected]>
The driver support 2 mechanisms in order to support AGE action:
1. Aging by counter - HW counter will be configured to the flow traffic, the driver polls the counter values efficiently to detect flow timeout.
2. Aging by ASO flow hit bit - HW ASO flow-hit bit is allocated for the flow, the driver polls the bit efficiently to detect flow timeout.
ASO bit is only single bit resource while counter is 16 bytes, hence, it is better to use ASO instead of counter for aging.
When a non-shared COUNT action is also configured to the flow, the driver can use the same counter also for AGE action and no need to create more ASO action for it.
The current code always uses ASO when it is supported in the device, change it to reuse the non-shared counter if it exists in the flow.
--- drivers/net/mlx5/mlx5_flow_dv.c | 149 ++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 47 deletions(-)
drivers/net/mlx5/mlx5_flow_dv.c +102 -47
@@ -7143,6 +7143,12 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,RTE_FLOW_ERROR_TYPE_UNSPECIFIED ,NULL , "Shared ASO age action is not supported for group 0"); +if (action_flags &MLX5_FLOW_ACTION_AGE ) +return rte_flow_error_set + (error,EINVAL , +RTE_FLOW_ERROR_TYPE_ACTION , +NULL , +"duplicate age actions set" ); action_flags |=MLX5_FLOW_ACTION_AGE ; ++actions_n;break ;
@@ -11162,6 +11168,47 @@ flow_dv_translate_create_aso_age(struct rte_eth_dev *dev,return age_idx; } +/** +* Prepares DV flow counter with aging configuration. +* Gets it by index when exists, creates a new one when doesn't. +* +* @param[in] dev +* Pointer to rte_eth_dev structure. +* @param[in] dev_flow +* Pointer to the mlx5_flow. +* @param[in, out] flow +* Pointer to the sub flow. +* @param[in] count +* Pointer to the counter action configuration. +* @param[in] age +* Pointer to the aging action configuration. +* @param[out] error +* Pointer to the error structure. +* +* @return +* Pointer to the counter, NULL otherwise. +*/ +static struct mlx5_flow_counter * +flow_dv_prepare_counter (struct rte_eth_dev *dev, +struct mlx5_flow *dev_flow, +struct rte_flow *flow, +const struct rte_flow_action_count *count, +const struct rte_flow_action_age *age, +struct rte_flow_error *error) +{ +if (!flow->counter) { + flow->counter =flow_dv_translate_create_counter (dev, dev_flow, + count, age); +if (!flow->counter) { +rte_flow_error_set (error, rte_errno, +RTE_FLOW_ERROR_TYPE_ACTION ,NULL , +"cannot create counter object." ); +return NULL ; + } + } +return flow_dv_counter_get_by_idx (dev, flow->counter,NULL ); +} +/** * Fill the flow with DV spec, lock free * (mutex should be acquired by caller).
@@ -11215,7 +11262,7 @@ flow_dv_translate(struct rte_eth_dev *dev, } mhdr_dummy;struct mlx5_flow_dv_modify_hdr_resource *mhdr_res = &mhdr_dummy.res;const struct rte_flow_action_count *count =NULL ; -const struct rte_flow_action_age *age =NULL ; +const struct rte_flow_action_age *non_shared_age =NULL ;union flow_dv_attr flow_attr = { .attr =0 };uint32_t tag_be;union mlx5_flow_tbl_key tbl_key;
@@ -11230,6 +11277,7 @@ flow_dv_translate(struct rte_eth_dev *dev,const struct rte_flow_action_sample *sample =NULL ;struct mlx5_flow_sub_actions_list *sample_act;uint32_t sample_act_pos =UINT32_MAX ; +uint32_t age_act_pos =UINT32_MAX ;uint32_t num_of_dest =0 ;int tmp_actions_n =0 ;uint32_t table;
@@ -11452,7 +11500,12 @@ flow_dv_translate(struct rte_eth_dev *dev, age_act =flow_aso_age_get_by_idx (dev, flow->age);__atomic_fetch_add (&age_act->refcnt,1 , __ATOMIC_RELAXED); - dev_flow->dv.actions[actions_n++] = age_act->dr_action; + age_act_pos = actions_n++; + action_flags |=MLX5_FLOW_ACTION_AGE ; +break ; +case RTE_FLOW_ACTION_TYPE_AGE : + non_shared_age = action->conf; + age_act_pos = actions_n++; action_flags |=MLX5_FLOW_ACTION_AGE ;break ;case MLX5_RTE_FLOW_ACTION_TYPE_COUNT :
@@ -11464,31 +11517,6 @@ flow_dv_translate(struct rte_eth_dev *dev,/* Save information first, will apply later. */ action_flags |=MLX5_FLOW_ACTION_COUNT ;break ; -case RTE_FLOW_ACTION_TYPE_AGE : -if (priv->sh->flow_hit_aso_en && attr->group) { -/* -* Create one shared age action, to be used -* by all sub-flows. -*/ -if (!flow->age) { - flow->age = -flow_dv_translate_create_aso_age - (dev, action->conf, - error); -if (!flow->age) -return rte_flow_error_set - (error, rte_errno, -RTE_FLOW_ERROR_TYPE_ACTION , -NULL , -"can't create ASO age action" ); - } - dev_flow->dv.actions[actions_n++] = - (flow_aso_age_get_by_idx - (dev, flow->age))->dr_action; - action_flags |=MLX5_FLOW_ACTION_AGE ; -break ; - } -/* Fall-through */ case RTE_FLOW_ACTION_TYPE_COUNT :if (!dev_conf->devx) {return rte_flow_error_set
@@ -11498,10 +11526,7 @@ flow_dv_translate(struct rte_eth_dev *dev, "count action not supported"); }/* Save information first, will apply later. */ -if (actions->type ==RTE_FLOW_ACTION_TYPE_COUNT ) - count = action->conf; -else - age = action->conf; + count = action->conf; action_flags |=MLX5_FLOW_ACTION_COUNT ;break ;case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN :
@@ -11801,27 +11826,57 @@ flow_dv_translate(struct rte_eth_dev *dev, dev_flow->dv.actions[modify_action_position] = handle->dvh.modify_hdr->action; } +/* +* Handle AGE and COUNT action by single HW counter +* when they are not shared. +*/ +if (action_flags &MLX5_FLOW_ACTION_AGE ) { +if ((non_shared_age && + count && !count->shared) || + !(priv->sh->flow_hit_aso_en && + attr->group)) { +/* Creates age by counters. */ + cnt_act =flow_dv_prepare_counter + (dev, dev_flow, + flow, count, + non_shared_age, + error); +if (!cnt_act) +return -rte_errno; + dev_flow->dv.actions[age_act_pos] = + cnt_act->action; +break ; + } +if (!flow->age && non_shared_age) { + flow->age = +flow_dv_translate_create_aso_age + (dev, + non_shared_age, + error); +if (!flow->age) +return rte_flow_error_set + (error, rte_errno, +RTE_FLOW_ERROR_TYPE_ACTION , +NULL , +"can't create ASO age action" ); + } + age_act =flow_aso_age_get_by_idx (dev, + flow->age); + dev_flow->dv.actions[age_act_pos] = + age_act->dr_action; + }if (action_flags &MLX5_FLOW_ACTION_COUNT ) {/* * Create one count action, to be used * by all sub-flows. */ -if (!flow->counter) { - flow->counter = -flow_dv_translate_create_counter - (dev, dev_flow, count, - age); -if (!flow->counter) -return rte_flow_error_set - (error, rte_errno, -RTE_FLOW_ERROR_TYPE_ACTION , -NULL ,"cannot create counter" -" object." ); - } - dev_flow->dv.actions[actions_n] = - (flow_dv_counter_get_by_idx (dev, - flow->counter,NULL ))->action; - actions_n++; + cnt_act =flow_dv_prepare_counter (dev, dev_flow, + flow, count, +NULL , error); +if (!cnt_act) +return -rte_errno; + dev_flow->dv.actions[actions_n++] = + cnt_act->action; }default :break ;
Signature · 1 line
2.18.1
Re: [dpdk-dev] [PATCH v2 0/5] Add support of indirect action API for count action.
In reply to Viacheslav OvsiienkoQuoted 10 lines · Viacheslav Ovsiienko
v1: http://patches.dpdk.org/project/dpdk/patch/[email protected]/
V2: patch rebaseMichael Baum (5):
net/mlx5: support flow count action handle app/testpmd: remove indirect RSS action query app/testpmd: support indirect counter action query net/mlx5: fix flow age event triggering net/mlx5: use aging by counter when counter is existed
Carried Ori's ack to testpmd patches from first version.
Series applied to dpdk-next-net/main, thanks.