From 4a9e5c999cd5ed8d17bcff4288d32e2c3ff82ac5 Mon Sep 17 00:00:00 2001 From: Rongwei Liu Date: Wed, 9 Mar 2022 14:08:29 +0200 Subject: [PATCH] net/mlx5: forbid multiple ASO actions in a single rule For now, only one ASO action is supported in a single flow rule. Flow rule with more than one ASO action should be rejected in the validation stage. Flow rule 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: stable@dpdk.org Signed-off-by: Rongwei Liu Acked-by: Xiaoyu Min Acked-by: Matan Azrad --- 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 d553e9dee3..1e9bd63635 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -6844,7 +6844,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; @@ -6914,6 +6914,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, bool shared_count = false; uint16_t udp_dport = 0; uint32_t tag_id = 0; + const struct rte_flow_action_age *non_shared_age = NULL; + const struct rte_flow_action_count *count = NULL; if (items == NULL) return -1; @@ -7453,6 +7455,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; @@ -7758,6 +7761,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); @@ -8054,6 +8058,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 rule. + * 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 rule"); /* * Hairpin flow will add one more TAG action in TX implicit mode. * In TX explicit mode, there will be no hairpin flow ID. -- 2.39.5