From b09c65fa4f8bb55880b6b36c849e4ed1bb815227 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlyuk Date: Wed, 1 Sep 2021 11:19:58 +0300 Subject: [PATCH] net/mlx5: fix flow indirect action reference counting When an indirect action is used in a flow rule with a pattern that causes RSS expansion, each device flow generated by the expansion incremented the reference counter of the action. When such a flow was destroyed, its action reference counter had been decremented only once. The action remained marked as being used and could not be destroyed. COUNT, AGE, and CONNTRACK indirect actions have been affected (for AGE the error was not immediately observable). Increment action counter only once for the original flow rule. Fixes: 81073e1f8ce1 ("net/mlx5: support shared age action") Fixes: 2d084f69aa26 ("net/mlx5: add translation of connection tracking action") Fixes: f3191849f2c2 ("net/mlx5: support flow count action handle") Cc: stable@dpdk.org Signed-off-by: Dmitry Kozlyuk Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow_dv.c | 37 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index b769ae4007..626513ce56 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -12840,10 +12840,13 @@ flow_dv_translate(struct rte_eth_dev *dev, MLX5_FLOW_FATE_QUEUE; break; case MLX5_RTE_FLOW_ACTION_TYPE_AGE: - flow->age = (uint32_t)(uintptr_t)(action->conf); - age_act = flow_aso_age_get_by_idx(dev, flow->age); - __atomic_fetch_add(&age_act->refcnt, 1, - __ATOMIC_RELAXED); + owner_idx = (uint32_t)(uintptr_t)action->conf; + age_act = flow_aso_age_get_by_idx(dev, owner_idx); + if (flow->age == 0) { + flow->age = owner_idx; + __atomic_fetch_add(&age_act->refcnt, 1, + __ATOMIC_RELAXED); + } age_act_pos = actions_n++; action_flags |= MLX5_FLOW_ACTION_AGE; break; @@ -12853,9 +12856,9 @@ flow_dv_translate(struct rte_eth_dev *dev, action_flags |= MLX5_FLOW_ACTION_AGE; break; case MLX5_RTE_FLOW_ACTION_TYPE_COUNT: - cnt_act = flow_dv_counter_get_by_idx(dev, - (uint32_t)(uintptr_t)action->conf, - NULL); + owner_idx = (uint32_t)(uintptr_t)action->conf; + cnt_act = flow_dv_counter_get_by_idx(dev, owner_idx, + NULL); MLX5_ASSERT(cnt_act != NULL); /** * When creating meter drop flow in drop table, the @@ -12866,10 +12869,12 @@ flow_dv_translate(struct rte_eth_dev *dev, dev_flow->dv.actions[actions_n++] = cnt_act->action; } else { - flow->counter = - (uint32_t)(uintptr_t)(action->conf); - __atomic_fetch_add(&cnt_act->shared_info.refcnt, - 1, __ATOMIC_RELAXED); + if (flow->counter == 0) { + flow->counter = owner_idx; + __atomic_fetch_add + (&cnt_act->shared_info.refcnt, + 1, __ATOMIC_RELAXED); + } /* Save information first, will apply later. */ action_flags |= MLX5_FLOW_ACTION_COUNT; } @@ -13192,9 +13197,13 @@ flow_dv_translate(struct rte_eth_dev *dev, else dev_flow->dv.actions[actions_n] = ct->dr_action_rply; - flow->indirect_type = MLX5_INDIRECT_ACTION_TYPE_CT; - flow->ct = owner_idx; - __atomic_fetch_add(&ct->refcnt, 1, __ATOMIC_RELAXED); + if (flow->ct == 0) { + flow->indirect_type = + MLX5_INDIRECT_ACTION_TYPE_CT; + flow->ct = owner_idx; + __atomic_fetch_add(&ct->refcnt, 1, + __ATOMIC_RELAXED); + } actions_n++; action_flags |= MLX5_FLOW_ACTION_CT; break; -- 2.20.1