X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_flow_meter.c;h=d7ce5cd2f6badd66924722c6025ad0f1b85ea82f;hb=05b405d581486651305551a9f7295f40388d95db;hp=e97a1d77a6ecef6dd39314acd59a3fb84052470c;hpb=4443201863933b27274a2ffc0d648bebc90e6b9b;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index e97a1d77a6..d7ce5cd2f6 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. */ @@ -519,7 +559,8 @@ static int __mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev, uint32_t policy_id, struct mlx5_flow_meter_policy *mtr_policy, - struct rte_mtr_error *error) + struct rte_mtr_error *error, + bool clear_l3t) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_sub_policy *sub_policy; @@ -550,7 +591,7 @@ __mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev, } } } - if (priv->sh->mtrmng->policy_idx_tbl) { + if (priv->sh->mtrmng->policy_idx_tbl && clear_l3t) { if (mlx5_l3t_clear_entry(priv->sh->mtrmng->policy_idx_tbl, policy_id)) { rte_spinlock_unlock(&mtr_policy->sl); @@ -708,7 +749,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev, policy->actions, error); if (ret) goto policy_add_err; - if (!is_rss) { + if (!is_rss && !mtr_policy->is_queue) { /* Create policy rules in HW. */ ret = mlx5_flow_create_policy_rules(dev, mtr_policy); if (ret) @@ -728,7 +769,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev, policy_add_err: if (mtr_policy) { ret = __mlx5_flow_meter_policy_delete(dev, policy_id, - mtr_policy, error); + mtr_policy, error, false); mlx5_free(mtr_policy); if (ret) return ret; @@ -775,7 +816,7 @@ mlx5_flow_meter_policy_delete(struct rte_eth_dev *dev, RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL, "Meter policy id is invalid. "); ret = __mlx5_flow_meter_policy_delete(dev, policy_id, mtr_policy, - error); + error, true); if (ret) return ret; mlx5_free(mtr_policy); @@ -1768,6 +1809,40 @@ mlx5_flow_meter_detach(struct mlx5_priv *priv, #endif } +/** + * Flush meter with Rx queue configuration. + * + * @param[in] dev + * Pointer to Ethernet device. + */ +void +mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_flow_meter_sub_policy *sub_policy; + struct mlx5_flow_meter_policy *mtr_policy; + void *entry; + uint32_t i, policy_idx; + + if (!priv->mtr_en) + return; + if (priv->sh->mtrmng->policy_idx_tbl && priv->sh->refcnt == 1) { + MLX5_L3T_FOREACH(priv->sh->mtrmng->policy_idx_tbl, + i, entry) { + policy_idx = *(uint32_t *)entry; + sub_policy = mlx5_ipool_get + (priv->sh->ipool[MLX5_IPOOL_MTR_POLICY], + policy_idx); + if (!sub_policy || !sub_policy->main_policy) + continue; + mtr_policy = sub_policy->main_policy; + if (mtr_policy->is_queue || mtr_policy->is_rss) + mlx5_flow_destroy_sub_policy_with_rxq(dev, + mtr_policy); + } + } +} + /** * Flush meter configuration. * @@ -1835,7 +1910,7 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) "meter policy invalid."); if (__mlx5_flow_meter_policy_delete(dev, i, sub_policy->main_policy, - error)) + error, true)) return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_POLICY_ID,