[v3,6/7] net/mlx5: check consistency of meter policy and profile

Message ID 20210721085421.13111-7-bingz@nvidia.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers
Series support yellow color policy in mlx5 |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Bing Zhao July 21, 2021, 8:54 a.m. UTC
  In the previous implementation, only green color policy was
supported in mlx5 PMD. Since yellow color policy is supported now,
the consistency of meter policy and profile should be checked.
  1. If the profile supports yellow but the policy doesn't, an error
     should be returned when creating the meter. Or else, there is
     no explicit steering action for the packets marked with yellow.
  2. If the policy supports yellow but the profile doesn't, it will
     be considered as a valid case. Even if no packet will be
     handled with the yellow steering action, it is just like that
     only the green policy presents.

Usually the green color is supported by default, but when it is
disabled intentionally with setting the CBS to a small value like
zero in the profile, the similar checking on green policy and
profile should also be done.

Signed-off-by: Bing Zhao <bingz@nvidia.com>
---
 drivers/net/mlx5/mlx5.h            |  6 ++++++
 drivers/net/mlx5/mlx5_flow_dv.c    |  4 ++++
 drivers/net/mlx5/mlx5_flow_meter.c | 20 ++++++++++++++++++--
 3 files changed, 28 insertions(+), 2 deletions(-)
  

Patch

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index ea16109972..3a8587b7cf 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -746,6 +746,10 @@  struct mlx5_flow_meter_policy {
 	/* Is queue action in policy table. */
 	uint32_t is_hierarchy:1;
 	/* Is meter action in policy table. */
+	uint32_t skip_y:1;
+	/* If yellow color policy is skipped. */
+	uint32_t skip_g:1;
+	/* If green color policy is skipped. */
 	rte_spinlock_t sl;
 	uint32_t ref_cnt;
 	/* Use count. */
@@ -866,6 +870,8 @@  struct mlx5_flow_meter_profile {
 		/**< srtcm_rfc2697 struct. */
 	};
 	uint32_t ref_cnt; /**< Use count. */
+	uint32_t g_support:1; /**< If G color will be generated. */
+	uint32_t y_support:1; /**< If Y color will be generated. */
 };
 
 /* 2 meters in each ASO cache line */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 97e297d5c2..7ea04ba6e5 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -15245,6 +15245,10 @@  __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 	for (i = 0; i < RTE_COLORS; i++) {
 		if (i < MLX5_MTR_RTE_COLORS)
 			act_cnt = &mtr_policy->act_cnt[i];
+		/* Skip the color policy actions creation. */
+		if ((i == RTE_COLOR_YELLOW && mtr_policy->skip_y) ||
+		    (i == RTE_COLOR_GREEN && mtr_policy->skip_g))
+			continue;
 		action_flags = 0;
 		for (act = actions[i];
 		     act && act->type != RTE_FLOW_ACTION_TYPE_END; act++) {
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 32ad4ea133..4f57b7e04e 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -333,6 +333,10 @@  mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
 	ebs_exp = exp;
 	srtcm->ebs_eir = rte_cpu_to_be_32(ebs_exp << ASO_DSEG_EBS_EXP_OFFSET |
 					  ebs_man << ASO_DSEG_EBS_MAN_OFFSET);
+	if (srtcm->cbs_cir)
+		fmp->g_support = 1;
+	if (srtcm->ebs_eir)
+		fmp->y_support = 1;
 	return 0;
 }
 
@@ -750,6 +754,10 @@  mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 		return -rte_mtr_error_set(error, ENOMEM,
 				RTE_MTR_ERROR_TYPE_METER_POLICY, NULL,
 				"Memory alloc failed for meter policy.");
+	if (policy_mode == MLX5_MTR_POLICY_MODE_OG)
+		mtr_policy->skip_y = 1;
+	else if (policy_mode == MLX5_MTR_POLICY_MODE_OY)
+		mtr_policy->skip_g = 1;
 	policy_size = sizeof(struct mlx5_flow_meter_policy);
 	for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
 		if (!(domain_bitmap & (1 << i)))
@@ -1132,13 +1140,13 @@  mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
 		if (!priv->config.dv_esw_en)
 			domain_bitmap &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT;
 	} else {
-		mtr_policy = mlx5_flow_meter_policy_find(dev,
-				params->meter_policy_id, &policy_idx);
 		if (!priv->sh->meter_aso_en)
 			return -rte_mtr_error_set(error, ENOTSUP,
 				RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
 				"Part of the policies cannot be "
 				"supported without ASO ");
+		mtr_policy = mlx5_flow_meter_policy_find(dev,
+				params->meter_policy_id, &policy_idx);
 		if (!mtr_policy)
 			return -rte_mtr_error_set(error, ENOENT,
 				RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
@@ -1149,6 +1157,14 @@  mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
 					MLX5_MTR_DOMAIN_EGRESS_BIT : 0) |
 				(mtr_policy->transfer ?
 					MLX5_MTR_DOMAIN_TRANSFER_BIT : 0);
+		if (fmp->g_support && mtr_policy->skip_g)
+			return -rte_mtr_error_set(error, ENOTSUP,
+					RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+					NULL, "Meter green policy is empty.");
+		if (fmp->y_support && mtr_policy->skip_y)
+			return -rte_mtr_error_set(error, ENOTSUP,
+					RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+					NULL, "Meter yellow policy is empty.");
 	}
 	/* Allocate the flow meter memory. */
 	if (priv->sh->meter_aso_en) {