net/mlx5: fix meter profile validation

Message ID 20210729160405.161982-1-bingz@nvidia.com (mailing list archive)
State Accepted, archived
Delegated to: Raslan Darawsheh
Headers
Series net/mlx5: fix meter profile validation |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/github-robot success github build: passed
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-testing fail Testing issues
ci/iol-mellanox-Performance success Performance Testing PASS

Commit Message

Bing Zhao July 29, 2021, 4:04 p.m. UTC
  After the support for yellow color and RFC2698 & RFC4115 were added,
the profile validation adjustment was missed. With this fix, the
validation is like below:
  1. Legacy metering only supports RFC2697 without EBS.
  2. ASO metering can support all the three profiles.
  3. For backward compatibility, none EBS with RFC2697 profile is
     still supported and the checking is done in the meter
     creation stage.

In the meanwhile, some checking which was done in the parameters
calculation stage is moved in the validation in order to skip the
useless checking.

Fixes: 33a7493c8df8 ("net/mlx5: support meter for trTCM profiles")

Signed-off-by: Bing Zhao <bingz@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h     |   7 +-
 drivers/net/mlx5/mlx5_flow_meter.c | 139 ++++++++++++++++++-----------
 2 files changed, 88 insertions(+), 58 deletions(-)
  

Comments

Raslan Darawsheh July 29, 2021, 8:04 p.m. UTC | #1
Hi,

> -----Original Message-----
> From: Bing Zhao <bingz@nvidia.com>
> Sent: Thursday, July 29, 2021 7:04 PM
> To: Slava Ovsiienko <viacheslavo@nvidia.com>; Matan Azrad
> <matan@nvidia.com>
> Cc: dev@dpdk.org; Ori Kam <orika@nvidia.com>; Raslan Darawsheh
> <rasland@nvidia.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>
> Subject: [PATCH] net/mlx5: fix meter profile validation
> 
> After the support for yellow color and RFC2698 & RFC4115 were added, the
> profile validation adjustment was missed. With this fix, the validation is like
> below:
>   1. Legacy metering only supports RFC2697 without EBS.
>   2. ASO metering can support all three profiles.
>   3. For backward compatibility, none EBS with RFC2697 profile is
>      still supported and the checking is done in the meter
>      creation stage.
> 
> In the meanwhile, some checking which was done in the parameters
> calculation stage is moved in the validation in order to skip the useless
> checking.
> 
> Fixes: 33a7493c8df8 ("net/mlx5: support meter for trTCM profiles")
> 
> Signed-off-by: Bing Zhao <bingz@nvidia.com>
> Acked-by: Matan Azrad <matan@nvidia.com>
> ---

Patch applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh
  

Patch

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 5b73a193ee..fdb20f5d49 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -3849,10 +3849,9 @@  enum {
 	MLX5_FLOW_COLOR_UNDEFINED,
 };
 
-/* Maximum value of srTCM metering parameters. */
-#define MLX5_SRTCM_CBS_MAX (0xFF * (1ULL << 0x1F))
-#define MLX5_SRTCM_CIR_MAX (8 * (1ULL << 30) * 0xFF)
-#define MLX5_SRTCM_EBS_MAX 0
+/* Maximum value of srTCM & trTCM metering parameters. */
+#define MLX5_SRTCM_XBS_MAX (0xFF * (1ULL << 0x1F))
+#define MLX5_SRTCM_XIR_MAX (8 * (1ULL << 30) * 0xFF)
 
 /* The bits meter color use. */
 #define MLX5_MTR_COLOR_BITS 8
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 2d91a6fcf0..0f51710907 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -130,6 +130,11 @@  mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_flow_meter_profile *fmp;
+	uint32_t ls_factor;
+	int ret;
+	uint64_t cir, cbs;
+	uint64_t eir, ebs;
+	uint64_t pir, pbs;
 
 	/* Profile must not be NULL. */
 	if (profile == NULL)
@@ -148,50 +153,83 @@  mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
 					  RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
 					  NULL,
 					  "Meter profile already exists.");
-	if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
-		if (priv->config.hca_attr.qos.flow_meter_old) {
-			/* Verify support for flow meter parameters. */
-			if (priv->sh->meter_aso_en && profile->packet_mode) {
-				if (profile->srtcm_rfc2697.cir > 0 &&
-					(profile->srtcm_rfc2697.cir <<
-					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
-					<= MLX5_SRTCM_CIR_MAX &&
-					profile->srtcm_rfc2697.cbs > 0 &&
-					(profile->srtcm_rfc2697.cbs <<
-					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
-					<= MLX5_SRTCM_CBS_MAX &&
-					(profile->srtcm_rfc2697.ebs <<
-					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
-					<= MLX5_SRTCM_EBS_MAX)
-					return 0;
-				return -rte_mtr_error_set
-					     (error, ENOTSUP,
-					      RTE_MTR_ERROR_TYPE_MTR_PARAMS,
-					      NULL,
-					      profile->srtcm_rfc2697.ebs ?
-					      "Metering value ebs must be 0." :
-					      "Invalid metering parameters.");
-			}
-			if (profile->srtcm_rfc2697.cir > 0 &&
-				profile->srtcm_rfc2697.cir <=
-						MLX5_SRTCM_CIR_MAX &&
-				profile->srtcm_rfc2697.cbs > 0 &&
-				profile->srtcm_rfc2697.cbs <=
-						MLX5_SRTCM_CBS_MAX &&
-				profile->srtcm_rfc2697.ebs <=
-						MLX5_SRTCM_EBS_MAX)
-				return 0;
+	if (!priv->sh->meter_aso_en) {
+		/* Old version is even not supported. */
+		if (!priv->config.hca_attr.qos.flow_meter_old)
 			return -rte_mtr_error_set(error, ENOTSUP,
-					RTE_MTR_ERROR_TYPE_MTR_PARAMS,
-					NULL,
-					profile->srtcm_rfc2697.ebs ?
-					"Metering value ebs must be 0." :
-					"Invalid metering parameters.");
+				RTE_MTR_ERROR_TYPE_METER_PROFILE,
+				NULL, "Metering is not supported.");
+		/* Old FW metering only supports srTCM. */
+		if (profile->alg != RTE_MTR_SRTCM_RFC2697) {
+			return -rte_mtr_error_set(error, ENOTSUP,
+				RTE_MTR_ERROR_TYPE_METER_PROFILE,
+				NULL, "Metering algorithm is not supported.");
+		} else if (profile->srtcm_rfc2697.ebs) {
+			/* EBS is not supported for old metering. */
+			return -rte_mtr_error_set(error, ENOTSUP,
+				RTE_MTR_ERROR_TYPE_METER_PROFILE,
+				NULL, "EBS is not supported.");
 		}
+		if (profile->packet_mode)
+			return -rte_mtr_error_set(error, ENOTSUP,
+				RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
+				"Metering algorithm packet mode is not supported.");
 	}
-	return -rte_mtr_error_set(error, ENOTSUP,
-				  RTE_MTR_ERROR_TYPE_METER_PROFILE,
-				  NULL, "Metering algorithm not supported.");
+	ls_factor = profile->packet_mode ? MLX5_MTRS_PPS_MAP_BPS_SHIFT : 0;
+	switch (profile->alg) {
+	case RTE_MTR_SRTCM_RFC2697:
+		cir = profile->srtcm_rfc2697.cir << ls_factor;
+		cbs = profile->srtcm_rfc2697.cbs << ls_factor;
+		ebs = profile->srtcm_rfc2697.ebs << ls_factor;
+		/* EBS could be zero for old metering. */
+		if (cir > 0 && cir <= MLX5_SRTCM_XIR_MAX &&
+		    cbs > 0 && cbs <= MLX5_SRTCM_XBS_MAX &&
+		    ebs <= MLX5_SRTCM_XBS_MAX) {
+			ret = 0;
+		} else {
+			ret = -rte_mtr_error_set(error, ENOTSUP,
+					RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
+					"Profile values out of range.");
+		}
+		break;
+	case RTE_MTR_TRTCM_RFC2698:
+		cir = profile->trtcm_rfc2698.cir << ls_factor;
+		cbs = profile->trtcm_rfc2698.cbs << ls_factor;
+		pir = profile->trtcm_rfc2698.pir << ls_factor;
+		pbs = profile->trtcm_rfc2698.pbs << ls_factor;
+		if (cir > 0 && cir <= MLX5_SRTCM_XIR_MAX &&
+		    cbs > 0 && cbs <= MLX5_SRTCM_XBS_MAX &&
+		    pir >= cir && pir <= (MLX5_SRTCM_XIR_MAX * 2) &&
+		    pbs >= cbs && pbs <= (MLX5_SRTCM_XBS_MAX * 2)) {
+			ret = 0;
+		} else {
+			ret = -rte_mtr_error_set(error, ENOTSUP,
+					RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
+					"Profile values out of range.");
+		}
+		break;
+	case RTE_MTR_TRTCM_RFC4115:
+		cir = profile->trtcm_rfc4115.cir << ls_factor;
+		cbs = profile->trtcm_rfc4115.cbs << ls_factor;
+		eir = profile->trtcm_rfc4115.eir << ls_factor;
+		ebs = profile->trtcm_rfc4115.ebs << ls_factor;
+		if (cir > 0 && cir <= MLX5_SRTCM_XIR_MAX &&
+		    cbs > 0 && cbs <= MLX5_SRTCM_XBS_MAX &&
+		    eir <= MLX5_SRTCM_XIR_MAX && ebs <= MLX5_SRTCM_XBS_MAX) {
+			ret = 0;
+		} else {
+			ret = -rte_mtr_error_set(error, ENOTSUP,
+					RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
+					"Profile values out of range.");
+		}
+		break;
+	default:
+		ret = -rte_mtr_error_set(error, ENOTSUP,
+					 RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
+					 "Unknown metering algorithm.");
+		break;
+	}
+	return ret;
 }
 
 /*
@@ -270,7 +308,7 @@  mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp)
  */
 static int
 mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
-			struct mlx5_priv *priv, struct rte_mtr_error *error)
+			   struct rte_mtr_error *error)
 {
 	struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm = &fmp->srtcm_prm;
 	uint8_t man, exp;
@@ -278,17 +316,6 @@  mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
 	uint32_t eir_exp, eir_man, ebs_exp, ebs_man;
 	uint64_t cir, cbs, eir, ebs;
 
-	if (!priv->sh->meter_aso_en) {
-		/* Legacy FW metering will only support srTCM. */
-		if (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)
-			return -rte_mtr_error_set(error, ENOTSUP,
-				RTE_MTR_ERROR_TYPE_METER_PROFILE,
-				NULL, "Metering algorithm is not supported.");
-		if (fmp->profile.packet_mode)
-			return -rte_mtr_error_set(error, ENOTSUP,
-				RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
-				"Metering algorithm packet mode is not supported.");
-	}
 	switch (fmp->profile.alg) {
 	case RTE_MTR_SRTCM_RFC2697:
 		cir = fmp->profile.srtcm_rfc2697.cir;
@@ -469,7 +496,7 @@  mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,
 	fmp->id = meter_profile_id;
 	fmp->profile = *profile;
 	/* Fill the flow meter parameters for the PRM. */
-	ret = mlx5_flow_meter_param_fill(fmp, priv, error);
+	ret = mlx5_flow_meter_param_fill(fmp, error);
 	if (ret)
 		goto error;
 	data.ptr = fmp;
@@ -1210,6 +1237,10 @@  mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
 		aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx);
 		fm = &aso_mtr->fm;
 	} else {
+		if (fmp->y_support)
+			return -rte_mtr_error_set(error, ENOMEM,
+				RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+				"Unsupported profile with yellow.");
 		legacy_fm = mlx5_ipool_zmalloc
 				(priv->sh->ipool[MLX5_IPOOL_MTR], &mtr_idx);
 		if (legacy_fm == NULL)