[dpdk-dev] [PATCH 2/2] net/mlx5: support meter PPS profile
From: Li Zhang <hidden>
Date: 2021-03-31 09:23:37
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Currently meter algorithms only supports bytes per second(BPS). Such as Single Rate Three Color Marker (srTCM rfc2697) Add packet_mode flag to support rate is packet per second. So that it can meter traffic by packet per second (PPS). Signed-off-by: Li Zhang <redacted> --- doc/guides/nics/mlx5.rst | 1 + drivers/net/mlx5/mlx5_flow_aso.c | 17 ++++--- drivers/net/mlx5/mlx5_flow_meter.c | 74 +++++++++++++++++++++++------- 3 files changed, 69 insertions(+), 23 deletions(-)
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 6e9a68baf5..1eb6d3d5da 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst@@ -415,6 +415,7 @@ Limitations green: QUEUE, RSS, PORT_ID, JUMP, MARK and SET_TAG. yellow: must be empty. red: must be DROP. + - meter profile packet mode is supported. Statistics ----------
diff --git a/drivers/net/mlx5/mlx5_flow_aso.c b/drivers/net/mlx5/mlx5_flow_aso.c
index 879252faa1..f34fc54fa6 100644
--- a/drivers/net/mlx5/mlx5_flow_aso.c
+++ b/drivers/net/mlx5/mlx5_flow_aso.c@@ -174,7 +174,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->sq_obj.aso_wqes[0]; i < size; ++i, ++wqe) {
@@ -187,11 +186,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)); } }
@@ -642,6 +636,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;
@@ -682,6 +677,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.packet_mode) + 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 2c08359107..4aa87fd53c 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c@@ -144,13 +144,19 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev, if (profile->alg == RTE_MTR_SRTCM_RFC2697) { if (priv->config.hca_attr.qos.flow_meter_old) { /* Verify support for flow meter 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; - else + 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,
@@ -158,6 +164,22 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev, 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; + 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."); } } return -rte_mtr_error_set(error, ENOTSUP,
@@ -241,20 +263,36 @@ 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; 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, RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL, "Metering algorithm not supported."); + if (!priv->sh->meter_aso_en && fmp->profile.packet_mode) + return -rte_mtr_error_set(error, ENOTSUP, + RTE_MTR_ERROR_TYPE_METER_PROFILE, + NULL, "Metering algorithm packet mode not supported."); + if (priv->sh->meter_aso_en && fmp->profile.packet_mode) { + cir = fmp->profile.srtcm_rfc2697.cir << + MLX5_MTRS_PPS_MAP_BPS_SHIFT; + cbs = fmp->profile.srtcm_rfc2697.cbs << + MLX5_MTRS_PPS_MAP_BPS_SHIFT; + ebs = fmp->profile.srtcm_rfc2697.ebs << + MLX5_MTRS_PPS_MAP_BPS_SHIFT; + } else { + cir = fmp->profile.srtcm_rfc2697.cir; + cbs = fmp->profile.srtcm_rfc2697.cbs; + ebs = fmp->profile.srtcm_rfc2697.ebs; + } /* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */ - mlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir, - &man, &exp); + mlx5_flow_meter_cir_man_exp_calc(cir, &man, &exp); /* Check if cir mantissa is too large. */ if (exp > ASO_DSEG_CIR_EXP_MASK) return -rte_mtr_error_set(error, ENOTSUP,
@@ -264,8 +302,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, - &man, &exp); + mlx5_flow_meter_xbs_man_exp_calc(cbs, &man, &exp); /* Check if cbs mantissa is too large. */ if (exp > ASO_DSEG_EXP_MASK) return -rte_mtr_error_set(error, ENOTSUP,
@@ -278,8 +315,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, - &man, &exp); + mlx5_flow_meter_xbs_man_exp_calc(ebs, &man, &exp); /* Check if ebs mantissa is too large. */ if (exp > ASO_DSEG_EXP_MASK) return -rte_mtr_error_set(error, ENOTSUP,
@@ -319,11 +355,15 @@ 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->srtcm_rfc2697_packet_mode_supported = 1; + } else { cap->n_max = 1 << qattr->log_max_flow_meter; + cap->srtcm_rfc2697_packet_mode_supported = 0; + } + cap->srtcm_rfc2697_byte_mode_supported = 1; cap->n_shared_max = cap->n_max; cap->identical = 1; cap->shared_identical = 1;
@@ -384,7 +424,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. */
--
2.21.0