diff mbox series

[RFC,v3,3/4] net/mlx5: support meter PPS profile

Message ID 20210301095350.183502-4-lizh@nvidia.com (mailing list archive)
State Superseded
Delegated to: Ferruh Yigit
Headers show
Series [RFC,v3,1/4] ethdev: add meter PPS profile | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Li Zhang March 1, 2021, 9:53 a.m. UTC
Currently meter algorithms only supports bytes per second(BPS).
Such as Single Rate Three Color Marker (srTCM rfc2697)
Add this new meter srTCMp algorithm to support rate is packet per second.
So that it can meter traffic by packet per second (PPS).

Signed-off-by: Li Zhang <lizh@nvidia.com>
---
 doc/guides/nics/mlx5.rst           |  1 +
 drivers/net/mlx5/mlx5.h            | 13 ++++--
 drivers/net/mlx5/mlx5_flow_aso.c   | 17 ++++---
 drivers/net/mlx5/mlx5_flow_meter.c | 71 ++++++++++++++++++++++++------
 4 files changed, 79 insertions(+), 23 deletions(-)
diff mbox series

Patch

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index a390a4b53c..93f5c0e4d4 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -362,6 +362,7 @@  Limitations
   - Green color is not supported with drop action.
   - Yellow detection is not supported.
   - Red color must be with drop action.
+  - meter srTCMp algorithm is supported.
 
 Statistics
 ----------
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 2790995dcc..16fa1b6c4d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -742,8 +742,13 @@  struct mlx5_flow_meter_info {
 	/**< Flow meter action. */
 };
 
-/* RFC2697 parameter structure. */
-struct mlx5_flow_meter_srtcm_rfc2697_prm {
+/* PPS(packets per second) map to BPS(Bytes per second).
+ * HW treat packet as 128bytes in PPS mode
+ */
+#define MLX5_MTRS_PPS_MAP_BPS_SHIFT 7
+
+/* RFC2697/PPS parameter structure. */
+struct mlx5_flow_meter_srtcm_prm {
 	rte_be32_t cbs_cir;
 	/*
 	 * bit 24-28: cbs_exponent, bit 16-23 cbs_mantissa,
@@ -763,8 +768,8 @@  struct mlx5_flow_meter_profile {
 	uint32_t id; /**< Profile id. */
 	struct rte_mtr_meter_profile profile; /**< Profile detail. */
 	union {
-		struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;
-		/**< srtcm_rfc2697 struct. */
+		struct mlx5_flow_meter_srtcm_prm srtcm_prm;
+		/**< srtcm_rfc2697/srtcm_pps struct. */
 	};
 	uint32_t ref_cnt; /**< Use count. */
 };
diff --git a/drivers/net/mlx5/mlx5_flow_aso.c b/drivers/net/mlx5/mlx5_flow_aso.c
index c9280b1f9d..3f3ba7e8fa 100644
--- a/drivers/net/mlx5/mlx5_flow_aso.c
+++ b/drivers/net/mlx5/mlx5_flow_aso.c
@@ -244,7 +244,6 @@  mlx5_aso_mtr_init_sq(struct mlx5_aso_sq *sq)
 	volatile struct mlx5_aso_wqe *restrict wqe;
 	int i;
 	int size = 1 << sq->log_desc_n;
-	uint32_t idx;
 
 	/* All the next fields state should stay constant. */
 	for (i = 0, wqe = &sq->wqes[0]; i < size; ++i, ++wqe) {
@@ -257,11 +256,6 @@  mlx5_aso_mtr_init_sq(struct mlx5_aso_sq *sq)
 			 (BYTEWISE_64BYTE << ASO_CSEG_DATA_MASK_MODE_OFFSET));
 		wqe->general_cseg.flags = RTE_BE32(MLX5_COMP_ALWAYS <<
 							 MLX5_COMP_MODE_OFFSET);
-		for (idx = 0; idx < MLX5_ASO_METERS_PER_WQE;
-			idx++)
-			wqe->aso_dseg.mtrs[idx].v_bo_sc_bbog_mm =
-				RTE_BE32((1 << ASO_DSEG_VALID_OFFSET) |
-				(MLX5_FLOW_COLOR_GREEN << ASO_DSEG_SC_OFFSET));
 	}
 }
 
@@ -744,6 +738,7 @@  mlx5_aso_mtr_sq_enqueue_single(struct mlx5_aso_sq *sq,
 {
 	volatile struct mlx5_aso_wqe *wqe = NULL;
 	struct mlx5_flow_meter_info *fm = NULL;
+	struct mlx5_flow_meter_profile *fmp;
 	uint16_t size = 1 << sq->log_desc_n;
 	uint16_t mask = size - 1;
 	uint16_t res = size - (uint16_t)(sq->head - sq->tail);
@@ -781,6 +776,16 @@  mlx5_aso_mtr_sq_enqueue_single(struct mlx5_aso_sq *sq,
 			RTE_BE32(MLX5_IFC_FLOW_METER_DISABLE_CBS_CIR_VAL);
 		wqe->aso_dseg.mtrs[dseg_idx].ebs_eir = 0;
 	}
+	fmp = fm->profile;
+	if (fmp->profile.alg == RTE_MTR_SRTCMP)
+		wqe->aso_dseg.mtrs[dseg_idx].v_bo_sc_bbog_mm =
+				RTE_BE32((1 << ASO_DSEG_VALID_OFFSET) |
+				(MLX5_FLOW_COLOR_GREEN << ASO_DSEG_SC_OFFSET) |
+				(MLX5_METER_MODE_PKT << ASO_DSEG_MTR_MODE));
+	else
+		wqe->aso_dseg.mtrs[dseg_idx].v_bo_sc_bbog_mm =
+				RTE_BE32((1 << ASO_DSEG_VALID_OFFSET) |
+				(MLX5_FLOW_COLOR_GREEN << ASO_DSEG_SC_OFFSET));
 	sq->head++;
 	sq->pi += 2;/* Each WQE contains 2 WQEBB's. */
 	rte_io_wmb();
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 49f6229ae6..cf2fe8c173 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -33,7 +33,7 @@  mlx5_flow_meter_action_create(struct mlx5_priv *priv,
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
 	struct mlx5dv_dr_flow_meter_attr mtr_init;
 	uint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)];
-	struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm =
+	struct mlx5_flow_meter_srtcm_prm *srtcm =
 						     &fm->profile->srtcm_prm;
 	uint32_t cbs_cir = rte_be_to_cpu_32(srtcm->cbs_cir);
 	uint32_t ebs_eir = rte_be_to_cpu_32(srtcm->ebs_eir);
@@ -157,6 +157,32 @@  mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
 					      "Invalid metering parameters.");
 		}
 	}
+	if (priv->sh->meter_aso_en &&
+		profile->alg == RTE_MTR_SRTCMP) {
+		if (priv->config.hca_attr.qos.srtcm_sup) {
+			/* Verify support for flow meter parameters. */
+			if (profile->srtcmp.cir > 0 &&
+			    (profile->srtcmp.cir <<
+					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+						<= MLX5_SRTCM_CIR_MAX &&
+			    profile->srtcmp.cbs > 0 &&
+			    (profile->srtcmp.cbs <<
+					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+						<= MLX5_SRTCM_CBS_MAX &&
+			    (profile->srtcmp.ebs <<
+					MLX5_MTRS_PPS_MAP_BPS_SHIFT)
+						<= MLX5_SRTCM_EBS_MAX)
+				return 0;
+			else
+				return -rte_mtr_error_set
+					     (error, ENOTSUP,
+					      RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+					      NULL,
+					      profile->srtcmp.ebs ?
+					      "Metering value ebs must be 0." :
+					      "Invalid metering parameters.");
+		}
+	}
 	return -rte_mtr_error_set(error, ENOTSUP,
 				  RTE_MTR_ERROR_TYPE_METER_PROFILE,
 				  NULL, "Metering algorithm not supported.");
@@ -238,19 +264,35 @@  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 rte_mtr_error *error)
+			struct mlx5_priv *priv, struct rte_mtr_error *error)
 {
-	struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm = &fmp->srtcm_prm;
+	struct mlx5_flow_meter_srtcm_prm *srtcm = &fmp->srtcm_prm;
 	uint8_t man, exp;
 	uint32_t cbs_exp, cbs_man, cir_exp, cir_man;
 	uint32_t ebs_exp, ebs_man;
+	uint64_t cir, cbs, ebs;
 
-	if (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)
-		return -rte_mtr_error_set(error, ENOTSUP,
+	if (fmp->profile.alg == RTE_MTR_SRTCM_RFC2697) {
+		cir = fmp->profile.srtcm_rfc2697.cir;
+		cbs = fmp->profile.srtcm_rfc2697.cbs;
+		ebs = fmp->profile.srtcm_rfc2697.ebs;
+	} else {
+		if (priv->sh->meter_aso_en &&
+			fmp->profile.alg == RTE_MTR_SRTCMP) {
+			cir = fmp->profile.srtcmp.cir <<
+				MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+			cbs = fmp->profile.srtcmp.cbs <<
+				MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+			ebs = fmp->profile.srtcmp.ebs <<
+				MLX5_MTRS_PPS_MAP_BPS_SHIFT;
+		} else {
+			return -rte_mtr_error_set(error, ENOTSUP,
 				RTE_MTR_ERROR_TYPE_METER_PROFILE,
 				NULL, "Metering algorithm not supported.");
+		}
+	}
 	/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */
-	mlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,
+	mlx5_flow_meter_cir_man_exp_calc(cir,
 				    &man, &exp);
 	/* Check if cir mantissa is too large. */
 	if (exp > ASO_DSEG_CIR_EXP_MASK)
@@ -261,7 +303,7 @@  mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
 	cir_man = man;
 	cir_exp = exp;
 	 /* cbs = cbs_mantissa * 2^cbs_exponent */
-	mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.cbs,
+	mlx5_flow_meter_xbs_man_exp_calc(cbs,
 				    &man, &exp);
 	/* Check if cbs mantissa is too large. */
 	if (exp > ASO_DSEG_EXP_MASK)
@@ -275,7 +317,7 @@  mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
 				cbs_man << ASO_DSEG_CBS_MAN_OFFSET |
 				cir_exp << ASO_DSEG_CIR_EXP_OFFSET |
 				cir_man);
-	mlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.ebs,
+	mlx5_flow_meter_xbs_man_exp_calc(ebs,
 				    &man, &exp);
 	/* Check if ebs mantissa is too large. */
 	if (exp > ASO_DSEG_EXP_MASK)
@@ -316,11 +358,14 @@  mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,
 					  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
 					  "Meter is not supported");
 	memset(cap, 0, sizeof(*cap));
-	if (priv->sh->meter_aso_en)
+	if (priv->sh->meter_aso_en) {
 	    /* 2 meters per one ASO cache line. */
 		cap->n_max = 1 << (qattr->log_max_num_meter_aso + 1);
-	else
+		cap->meter_srtcmp_n_max = qattr->srtcm_sup ? cap->n_max : 0;
+	} else {
 		cap->n_max = 1 << qattr->log_max_flow_meter;
+		cap->meter_srtcmp_n_max = 0;
+	}
 	cap->n_shared_max = cap->n_max;
 	cap->identical = 1;
 	cap->shared_identical = 1;
@@ -382,7 +427,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, error);
+	ret = mlx5_flow_meter_param_fill(fmp, priv, error);
 	if (ret)
 		goto error;
 	/* Add to list. */
@@ -539,7 +584,7 @@  mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id,
 static int
 mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
 		struct mlx5_flow_meter_info *fm,
-		const struct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm,
+		const struct mlx5_flow_meter_srtcm_prm *srtcm,
 		uint64_t modify_bits, uint32_t active_state, uint32_t is_enable)
 {
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
@@ -899,7 +944,7 @@  mlx5_flow_meter_modify_state(struct mlx5_priv *priv,
 			     uint32_t new_state,
 			     struct rte_mtr_error *error)
 {
-	static const struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm = {
+	static const struct mlx5_flow_meter_srtcm_prm srtcm = {
 		.cbs_cir = RTE_BE32(MLX5_IFC_FLOW_METER_DISABLE_CBS_CIR_VAL),
 		.ebs_eir = 0,
 	};