Skip to content

Commit

Permalink
net/mlx5: support meter for trTCM profiles
Browse files Browse the repository at this point in the history
The support of RFC2698 and RFC4115 are added in mlx5 PMD. Only the
ASO metering supports these two profiles.

Signed-off-by: Bing Zhao <[email protected]>
Acked-by: Matan Azrad <[email protected]>
  • Loading branch information
zorrohahaha authored and tmonjalo committed Jul 22, 2021
1 parent 4d648fa commit 33a7493
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 44 deletions.
1 change: 1 addition & 0 deletions doc/guides/nics/mlx5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ Limitations
- RED: must be DROP.
- Policy actions of RSS for green and yellow should have the same configuration except queues.
- meter profile packet mode is supported.
- meter profiles of RFC2697, RFC2698 and RFC4115 are supported.

- Integrity:

Expand Down
1 change: 1 addition & 0 deletions doc/guides/rel_notes/release_21_08.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ New Features
* Added Sub-Function support based on auxiliary bus.
* Added support for meter hierarchy.
* Added support for metering policy actions of yellow color.
* Added support for metering trTCM RFC2698 and RFC4115.
* Added devargs options ``allow_duplicate_pattern``.
* Added matching on IPv4 Internet Header Length (IHL).
* Added support for matching on VXLAN header last 8-bits reserved field.
Expand Down
5 changes: 3 additions & 2 deletions drivers/common/mlx5/mlx5_prm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3031,11 +3031,12 @@ struct mlx5_aso_mtr_dseg {
#define ASO_DSEG_VALID_OFFSET 31
#define ASO_DSEG_BO_OFFSET 30
#define ASO_DSEG_SC_OFFSET 28
#define ASO_DSEG_BBOG_OFFSET 27
#define ASO_DSEG_MTR_MODE 24
#define ASO_DSEG_CBS_EXP_OFFSET 24
#define ASO_DSEG_CBS_MAN_OFFSET 16
#define ASO_DSEG_CIR_EXP_MASK 0x1F
#define ASO_DSEG_CIR_EXP_OFFSET 8
#define ASO_DSEG_XIR_EXP_MASK 0x1F
#define ASO_DSEG_XIR_EXP_OFFSET 8
#define ASO_DSEG_EBS_EXP_OFFSET 24
#define ASO_DSEG_EBS_MAN_OFFSET 16
#define ASO_DSEG_EXP_MASK 0x1F
Expand Down
23 changes: 20 additions & 3 deletions drivers/net/mlx5/mlx5_flow_aso.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,10 +747,27 @@ mlx5_aso_mtr_sq_enqueue_single(struct mlx5_aso_sq *sq,
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));
/* Only needed for RFC2697. */
if (fm->profile->srtcm_prm.ebs_eir)
switch (fmp->profile.alg) {
case RTE_MTR_SRTCM_RFC2697:
/* Only needed for RFC2697. */
if (fm->profile->srtcm_prm.ebs_eir)
wqe->aso_dseg.mtrs[dseg_idx].v_bo_sc_bbog_mm |=
RTE_BE32(1 << ASO_DSEG_BO_OFFSET);
break;
case RTE_MTR_TRTCM_RFC2698:
wqe->aso_dseg.mtrs[dseg_idx].v_bo_sc_bbog_mm |=
RTE_BE32(1 << ASO_DSEG_BO_OFFSET);
RTE_BE32(1 << ASO_DSEG_BBOG_OFFSET);
break;
case RTE_MTR_TRTCM_RFC4115:
default:
break;
}
/*
* Note:
* Due to software performance reason, the token fields will not be
* set when posting the WQE to ASO SQ. It will be filled by the HW
* automatically.
*/
sq->head++;
sq->pi += 2;/* Each WQE contains 2 WQEBB's. */
rte_io_wmb();
Expand Down
112 changes: 73 additions & 39 deletions drivers/net/mlx5/mlx5_flow_meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ mlx5_flow_meter_action_create(struct mlx5_priv *priv,
MLX5_SET(flow_meter_parameters, fmp, cbs_exponent, val);
val = (cbs_cir >> ASO_DSEG_CBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;
MLX5_SET(flow_meter_parameters, fmp, cbs_mantissa, val);
val = (cbs_cir >> ASO_DSEG_CIR_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
val = (cbs_cir >> ASO_DSEG_XIR_EXP_OFFSET) & ASO_DSEG_EXP_MASK;
MLX5_SET(flow_meter_parameters, fmp, cir_exponent, val);
val = (cbs_cir & ASO_DSEG_MAN_MASK);
MLX5_SET(flow_meter_parameters, fmp, cir_mantissa, val);
Expand Down Expand Up @@ -194,18 +194,18 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
NULL, "Metering algorithm not supported.");
}

/**
* Calculate mantissa and exponent for cir.
/*
* Calculate mantissa and exponent for cir / eir.
*
* @param[in] cir
* @param[in] xir
* Value to be calculated.
* @param[out] man
* Pointer to the mantissa.
* @param[out] exp
* Pointer to the exp.
*/
static void
mlx5_flow_meter_cir_man_exp_calc(int64_t cir, uint8_t *man, uint8_t *exp)
static inline void
mlx5_flow_meter_xir_man_exp_calc(int64_t xir, uint8_t *man, uint8_t *exp)
{
int64_t _cir;
int64_t delta = INT64_MAX;
Expand All @@ -216,8 +216,8 @@ mlx5_flow_meter_cir_man_exp_calc(int64_t cir, uint8_t *man, uint8_t *exp)
for (m = 0; m <= 0xFF; m++) { /* man width 8 bit */
for (e = 0; e <= 0x1F; e++) { /* exp width 5bit */
_cir = (1000000000ULL * m) >> e;
if (llabs(cir - _cir) <= delta) {
delta = llabs(cir - _cir);
if (llabs(xir - _cir) <= delta) {
delta = llabs(xir - _cir);
_man = m;
_exp = e;
}
Expand All @@ -227,7 +227,7 @@ mlx5_flow_meter_cir_man_exp_calc(int64_t cir, uint8_t *man, uint8_t *exp)
*exp = _exp;
}

/**
/*
* Calculate mantissa and exponent for xbs.
*
* @param[in] xbs
Expand All @@ -237,7 +237,7 @@ mlx5_flow_meter_cir_man_exp_calc(int64_t cir, uint8_t *man, uint8_t *exp)
* @param[out] exp
* Pointer to the exp.
*/
static void
static inline void
mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp)
{
int _exp;
Expand Down Expand Up @@ -275,37 +275,63 @@ mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
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;
uint32_t eir_exp, eir_man, ebs_exp, ebs_man;
uint64_t cir, cbs, eir, ebs;

if (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)
return -rte_mtr_error_set(error, ENOTSUP,
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 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 {
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;
cbs = fmp->profile.srtcm_rfc2697.cbs;
eir = 0;
ebs = fmp->profile.srtcm_rfc2697.ebs;
break;
case RTE_MTR_TRTCM_RFC2698:
MLX5_ASSERT(fmp->profile.trtcm_rfc2698.pir >
fmp->profile.trtcm_rfc2698.cir &&
fmp->profile.trtcm_rfc2698.pbs >
fmp->profile.trtcm_rfc2698.cbs);
cir = fmp->profile.trtcm_rfc2698.cir;
cbs = fmp->profile.trtcm_rfc2698.cbs;
/* EIR / EBS are filled with PIR / PBS. */
eir = fmp->profile.trtcm_rfc2698.pir;
ebs = fmp->profile.trtcm_rfc2698.pbs;
break;
case RTE_MTR_TRTCM_RFC4115:
cir = fmp->profile.trtcm_rfc4115.cir;
cbs = fmp->profile.trtcm_rfc4115.cbs;
eir = fmp->profile.trtcm_rfc4115.eir;
ebs = fmp->profile.trtcm_rfc4115.ebs;
break;
default:
return -rte_mtr_error_set(error, EINVAL,
RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL,
"Metering algorithm mode is invalid");
}
/* Adjust the values for PPS mode. */
if (fmp->profile.packet_mode) {
cir <<= MLX5_MTRS_PPS_MAP_BPS_SHIFT;
cbs <<= MLX5_MTRS_PPS_MAP_BPS_SHIFT;
eir <<= MLX5_MTRS_PPS_MAP_BPS_SHIFT;
ebs <<= MLX5_MTRS_PPS_MAP_BPS_SHIFT;
}
/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */
mlx5_flow_meter_cir_man_exp_calc(cir, &man, &exp);
mlx5_flow_meter_xir_man_exp_calc(cir, &man, &exp);
/* Check if cir mantissa is too large. */
if (exp > ASO_DSEG_CIR_EXP_MASK)
if (exp > ASO_DSEG_XIR_EXP_MASK)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
"meter profile parameter cir is"
" not supported.");
"meter profile parameter cir is not supported.");
cir_man = man;
cir_exp = exp;
/* cbs = cbs_mantissa * 2^cbs_exponent */
Expand All @@ -314,25 +340,33 @@ mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,
if (exp > ASO_DSEG_EXP_MASK)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
"meter profile parameter cbs is"
" not supported.");
"meter profile parameter cbs is not supported.");
cbs_man = man;
cbs_exp = exp;
srtcm->cbs_cir = rte_cpu_to_be_32(cbs_exp << ASO_DSEG_CBS_EXP_OFFSET |
cbs_man << ASO_DSEG_CBS_MAN_OFFSET |
cir_exp << ASO_DSEG_CIR_EXP_OFFSET |
cir_exp << ASO_DSEG_XIR_EXP_OFFSET |
cir_man);
mlx5_flow_meter_xir_man_exp_calc(eir, &man, &exp);
/* Check if eir mantissa is too large. */
if (exp > ASO_DSEG_XIR_EXP_MASK)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
"meter profile parameter eir is not supported.");
eir_man = man;
eir_exp = 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,
RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,
"meter profile parameter ebs is"
" not supported.");
"meter profile parameter ebs is not supported.");
ebs_man = man;
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);
ebs_man << ASO_DSEG_EBS_MAN_OFFSET |
eir_exp << ASO_DSEG_XIR_EXP_OFFSET |
eir_man);
if (srtcm->cbs_cir)
fmp->g_support = 1;
if (srtcm->ebs_eir)
Expand Down Expand Up @@ -1008,7 +1042,7 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
cbs_mantissa, val);
}
if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR) {
val = (cbs_cir >> ASO_DSEG_CIR_EXP_OFFSET) &
val = (cbs_cir >> ASO_DSEG_XIR_EXP_OFFSET) &
ASO_DSEG_EXP_MASK;
MLX5_SET(flow_meter_parameters, attr,
cir_exponent, val);
Expand Down Expand Up @@ -1389,7 +1423,7 @@ mlx5_flow_meter_modify_state(struct mlx5_priv *priv,
&srtcm, modify_bits, 0, 0);
else
ret = mlx5_flow_meter_action_modify(priv, fm,
&fm->profile->srtcm_prm,
&fm->profile->srtcm_prm,
modify_bits, 0, 1);
if (ret)
return -rte_mtr_error_set(error, -ret,
Expand Down

0 comments on commit 33a7493

Please sign in to comment.