From: Xiaoyu Min <jack...@nvidia.com> The indirect counter action is taked as _shared_ counter between the flows use it.
This _shared_ counter is gotten from counter pool at time the indirect action is created. And be put back to counter pool when indirect action is destroyed. Signed-off-by: Xiaoyu Min <jack...@nvidia.com> --- drivers/net/mlx5/mlx5_flow.h | 3 + drivers/net/mlx5/mlx5_flow_hw.c | 104 +++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index c982cb953a..a39dacc60a 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1148,6 +1148,9 @@ struct mlx5_action_construct_data { uint32_t level; /* RSS level. */ uint32_t idx; /* Shared action index. */ } shared_rss; + struct { + uint32_t id; + } shared_counter; }; }; diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index de82396a04..92b61b63d1 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -536,6 +536,44 @@ __flow_hw_act_data_shared_rss_append(struct mlx5_priv *priv, return 0; } +/** + * Append shared counter action to the dynamic action list. + * + * @param[in] priv + * Pointer to the port private data structure. + * @param[in] acts + * Pointer to the template HW steering DR actions. + * @param[in] type + * Action type. + * @param[in] action_src + * Offset of source rte flow action. + * @param[in] action_dst + * Offset of destination DR action. + * @param[in] cnt_id + * Shared counter id. + * + * @return + * 0 on success, negative value otherwise and rte_errno is set. + */ +static __rte_always_inline int +__flow_hw_act_data_shared_cnt_append(struct mlx5_priv *priv, + struct mlx5_hw_actions *acts, + enum rte_flow_action_type type, + uint16_t action_src, + uint16_t action_dst, + cnt_id_t cnt_id) +{ struct mlx5_action_construct_data *act_data; + + act_data = __flow_hw_act_data_alloc(priv, type, action_src, action_dst); + if (!act_data) + return -1; + act_data->type = type; + act_data->shared_counter.id = cnt_id; + LIST_INSERT_HEAD(&acts->act_list, act_data, next); + return 0; +} + + /** * Translate shared indirect action. * @@ -577,6 +615,13 @@ flow_hw_shared_action_translate(struct rte_eth_dev *dev, action_src, action_dst, idx, shared_rss)) return -1; break; + case MLX5_INDIRECT_ACTION_TYPE_COUNT: + if (__flow_hw_act_data_shared_cnt_append(priv, acts, + (enum rte_flow_action_type) + MLX5_RTE_FLOW_ACTION_TYPE_COUNT, + action_src, action_dst, act_idx)) + return -1; + break; default: DRV_LOG(WARNING, "Unsupported shared action type:%d", type); break; @@ -1454,6 +1499,13 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, (dev, &act_data, item_flags, rule_act)) return -1; break; + case MLX5_INDIRECT_ACTION_TYPE_COUNT: + if (mlx5_hws_cnt_pool_get_action_offset(priv->hws_cpool, + act_idx, + &rule_act->action, + &rule_act->counter.offset)) + return -1; + break; default: DRV_LOG(WARNING, "Unsupported shared action type:%d", type); break; @@ -1761,6 +1813,17 @@ flow_hw_actions_construct(struct rte_eth_dev *dev, return ret; job->flow->cnt_id = cnt_id; break; + case MLX5_RTE_FLOW_ACTION_TYPE_COUNT: + ret = mlx5_hws_cnt_pool_get_action_offset + (priv->hws_cpool, + act_data->shared_counter.id, + &rule_acts[act_data->action_dst].action, + &rule_acts[act_data->action_dst].counter.offset + ); + if (ret != 0) + return ret; + job->flow->cnt_id = act_data->shared_counter.id; + break; default: break; } @@ -4860,10 +4923,28 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue, void *user_data, struct rte_flow_error *error) { + struct rte_flow_action_handle *handle = NULL; + struct mlx5_priv *priv = dev->data->dev_private; + cnt_id_t cnt_id; + RTE_SET_USED(queue); RTE_SET_USED(attr); RTE_SET_USED(user_data); - return flow_dv_action_create(dev, conf, action, error); + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_COUNT: + if (mlx5_hws_cnt_shared_get(priv->hws_cpool, &cnt_id)) + rte_flow_error_set(error, ENODEV, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "counter are not configured!"); + else + handle = (struct rte_flow_action_handle *) + (uintptr_t)cnt_id; + break; + default: + handle = flow_dv_action_create(dev, conf, action, error); + } + return handle; } /** @@ -4927,10 +5008,19 @@ flow_hw_action_handle_destroy(struct rte_eth_dev *dev, uint32_t queue, void *user_data, struct rte_flow_error *error) { + uint32_t act_idx = (uint32_t)(uintptr_t)handle; + uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET; + struct mlx5_priv *priv = dev->data->dev_private; + RTE_SET_USED(queue); RTE_SET_USED(attr); RTE_SET_USED(user_data); - return flow_dv_action_destroy(dev, handle, error); + switch (type) { + case MLX5_INDIRECT_ACTION_TYPE_COUNT: + return mlx5_hws_cnt_shared_put(priv->hws_cpool, &act_idx); + default: + return flow_dv_action_destroy(dev, handle, error); + } } static int @@ -5075,7 +5165,15 @@ flow_hw_action_query(struct rte_eth_dev *dev, const struct rte_flow_action_handle *handle, void *data, struct rte_flow_error *error) { - return flow_dv_action_query(dev, handle, data, error); + uint32_t act_idx = (uint32_t)(uintptr_t)handle; + uint32_t type = act_idx >> MLX5_INDIRECT_ACTION_TYPE_OFFSET; + + switch (type) { + case MLX5_INDIRECT_ACTION_TYPE_COUNT: + return flow_hw_query_counter(dev, act_idx, data, error); + default: + return flow_dv_action_query(dev, handle, data, error); + } } const struct mlx5_flow_driver_ops mlx5_flow_hw_drv_ops = { -- 2.25.1