For now, only one ASO action is supported in a single flow. Flow with more than one ASO action should be rejected in the validation stage.
Flow with action non-shared AGE and COUNT together should be treated as non-ASO because AGE will fall back to use HW counter, not ASO hit object. Group 0 will use HW counter for AGE action even if no COUNT action. This commit will reject patterns (no matter which group if transfer) like: 1. group 1 pattern... / end actions age / meter / end 2. group 1 pattern... / end actions conntrack / meter / end 3. group 1 pattern... / end actions age / conntrack... / end If AGE comes together with COUNT in the above patterns, it's allowed. Fixes: daed4b6e ("net/mlx5: use aging by counter when counter exists") Cc: sta...@dpdk.org Signed-off-by: Rongwei Liu <rongw...@nvidia.com> Acked-by: Xiaoyu Min <jack...@nvidia.com> Acked-by: Matan Azrad <ma...@nvidia.com> --- drivers/net/mlx5/mlx5_flow_dv.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 29751e7eda..fccc4a9301 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -6862,7 +6862,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, bool external, int hairpin, struct rte_flow_error *error) { int ret; - uint64_t action_flags = 0; + uint64_t aso_mask, action_flags = 0; uint64_t item_flags = 0; uint64_t last_item = 0; uint8_t next_protocol = 0xff; @@ -6931,6 +6931,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, bool def_policy = false; bool shared_count = false; uint16_t udp_dport = 0; + const struct rte_flow_action_age *non_shared_age = NULL; + const struct rte_flow_action_count *count = NULL; if (items == NULL) return -1; @@ -7468,6 +7470,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, attr, error); if (ret < 0) return ret; + count = actions->conf; action_flags |= MLX5_FLOW_ACTION_COUNT; ++actions_n; break; @@ -7773,6 +7776,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, ++actions_n; break; case RTE_FLOW_ACTION_TYPE_AGE: + non_shared_age = actions->conf; ret = flow_dv_validate_action_age(action_flags, actions, dev, error); @@ -8048,6 +8052,20 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, "cannot be done before meter action"); } } + /* + * Only support one ASO action in a single flow. + * non-shared AGE + counter will fallback to use HW counter, no ASO hit object. + * Group 0 uses HW counter for AGE too even if no counter action. + */ + aso_mask = (action_flags & MLX5_FLOW_ACTION_METER && priv->sh->meter_aso_en) << 2 | + (action_flags & MLX5_FLOW_ACTION_CT && priv->sh->ct_aso_en) << 1 | + (action_flags & MLX5_FLOW_ACTION_AGE && + !(non_shared_age && count) && + (attr->group || (attr->transfer && priv->fdb_def_rule)) && + priv->sh->flow_hit_aso_en); + if (__builtin_popcountl(aso_mask) > 1) + return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "unsupported combining AGE, METER, CT ASO actions in a single flow"); /* * Hairpin flow will add one more TAG action in TX implicit mode. * In TX explicit mode, there will be no hairpin flow ID. -- 2.27.0