diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 4b4e043082..41ae2396d9 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -107,6 +107,7 @@ Features - 21844 flow priorities for ingress or egress flow groups greater than 0 and for any transfer flow group. - Flow metering, including meter policy API. +- Flow meter hierarchy. - Flow integrity offload API. - Connection tracking. - Sub-Function representors. @@ -1931,3 +1932,19 @@ on port X and to be shared with a port Y on the same switch domain by the next w .. code-block:: console flow create X ingress transfer pattern eth / port_id id is Y / end actions meter mtr_id M / end + +How to use meter hierarchy +-------------------------- + +This section demonstrates how to create and use a meter hierarchy. +A termination meter M can be the policy green action of another termination meter N. +The two meters are chained together as a chain. Using meter N in a flow will apply +both the meters in hierarchy on that flow. + +.. code-block:: console + + add port meter policy 0 1 g_actions queue index 0 / end y_actions end r_actions drop / end + create port meter 0 M 1 1 yes 0xffff 1 0 + add port meter policy 0 2 g_actions meter mtr_id M / end y_actions end r_actions drop / end + create port meter 0 N 2 2 yes 0xffff 1 0 + flow create 0 ingress group 1 pattern eth / end actions meter mtr_id N / end diff --git a/doc/guides/rel_notes/release_21_08.rst b/doc/guides/rel_notes/release_21_08.rst index c92e016783..ddd172b34a 100644 --- a/doc/guides/rel_notes/release_21_08.rst +++ b/doc/guides/rel_notes/release_21_08.rst @@ -84,6 +84,10 @@ New Features * Added net/cnxk driver which provides the support for the integrated ethernet device. +* **Updated Mellanox mlx5 driver.** + + * Added support for meter hierarchy. + * **Added support for Marvell CNXK crypto driver.** * Added cnxk crypto PMD which provides support for an integrated diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index c7e8461b15..2e56e7c83c 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -16862,6 +16862,78 @@ flow_dv_action_validate(struct rte_eth_dev *dev, } } +/** + * Validate the meter hierarchy chain for meter policy. + * + * @param[in] dev + * Pointer to the Ethernet device structure. + * @param[in] meter_id + * Meter id. + * @param[in] action_flags + * Holds the actions detected until now. + * @param[out] is_rss + * Is RSS or not. + * @param[out] hierarchy_domain + * The domain bitmap for hierarchy policy. + * @param[out] error + * Perform verbose error reporting if not NULL. Initialized in case of + * error only. + * + * @return + * 0 on success, otherwise negative errno value with error set. + */ +static int +flow_dv_validate_policy_mtr_hierarchy(struct rte_eth_dev *dev, + uint32_t meter_id, + uint64_t action_flags, + bool *is_rss, + uint8_t *hierarchy_domain, + struct rte_mtr_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_flow_meter_info *fm; + struct mlx5_flow_meter_policy *policy; + uint8_t cnt = 1; + + if (action_flags & (MLX5_FLOW_FATE_ACTIONS | + MLX5_FLOW_FATE_ESWITCH_ACTIONS)) + return -rte_mtr_error_set(error, EINVAL, + RTE_MTR_ERROR_TYPE_POLICER_ACTION_GREEN, + NULL, + "Multiple fate actions not supported."); + while (true) { + fm = mlx5_flow_meter_find(priv, meter_id, NULL); + if (!fm) + return -rte_mtr_error_set(error, EINVAL, + RTE_MTR_ERROR_TYPE_MTR_ID, NULL, + "Meter not found in meter hierarchy."); + if (fm->def_policy) + return -rte_mtr_error_set(error, EINVAL, + RTE_MTR_ERROR_TYPE_MTR_ID, NULL, + "Non termination meter not supported in hierarchy."); + policy = mlx5_flow_meter_policy_find(dev, fm->policy_id, NULL); + MLX5_ASSERT(policy); + if (!policy->is_hierarchy) { + if (policy->transfer) + *hierarchy_domain |= + MLX5_MTR_DOMAIN_TRANSFER_BIT; + if (policy->ingress) + *hierarchy_domain |= + MLX5_MTR_DOMAIN_INGRESS_BIT; + if (policy->egress) + *hierarchy_domain |= MLX5_MTR_DOMAIN_EGRESS_BIT; + *is_rss = policy->is_rss; + break; + } + meter_id = policy->act_cnt[RTE_COLOR_GREEN].next_mtr_id; + if (++cnt >= MLX5_MTR_CHAIN_MAX_NUM) + return -rte_mtr_error_set(error, EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY, NULL, + "Exceed max hierarchy meter number."); + } + return 0; +} + /** * Validate meter policy actions. * Dispatcher for action type specific validation. @@ -16897,6 +16969,8 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev, struct rte_flow_error flow_err; uint8_t domain_color[RTE_COLORS] = {0}; uint8_t def_domain = MLX5_MTR_ALL_DOMAIN_BIT; + uint8_t hierarchy_domain = 0; + const struct rte_flow_action_meter *mtr; if (!priv->config.dv_esw_en) def_domain &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT; @@ -17074,6 +17148,27 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev, ++actions_n; action_flags |= MLX5_FLOW_ACTION_JUMP; break; + case RTE_FLOW_ACTION_TYPE_METER: + if (i != RTE_COLOR_GREEN) + return -rte_mtr_error_set(error, + ENOTSUP, + RTE_MTR_ERROR_TYPE_METER_POLICY, + NULL, flow_err.message ? + flow_err.message : + "Meter hierarchy only supports GREEN color."); + mtr = act->conf; + ret = flow_dv_validate_policy_mtr_hierarchy(dev, + mtr->mtr_id, + action_flags, + is_rss, + &hierarchy_domain, + error); + if (ret) + return ret; + ++actions_n; + action_flags |= + MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY; + break; default: return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_POLICY, @@ -17094,6 +17189,9 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev, * so MARK action only in ingress domain. */ domain_color[i] = MLX5_MTR_DOMAIN_INGRESS_BIT; + else if (action_flags & + MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY) + domain_color[i] = hierarchy_domain; else domain_color[i] = def_domain; /*