X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_flow_meter.c;h=06ab7c4a882bfcac7aca9b50921014ef4bbc452e;hb=80f872ee0222e3936856e43a693168425b1c78ae;hp=0f51710907d205c37e1d8e1dd98a7a27d5076a90;hpb=8a0fca1101212c0980b8c007359b843d12854c7e;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index 0f51710907..06ab7c4a88 100644 --- a/drivers/net/mlx5/mlx5_flow_meter.c +++ b/drivers/net/mlx5/mlx5_flow_meter.c @@ -155,7 +155,7 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev, "Meter profile already exists."); if (!priv->sh->meter_aso_en) { /* Old version is even not supported. */ - if (!priv->config.hca_attr.qos.flow_meter_old) + if (!priv->sh->cdev->config.hca_attr.qos.flow_meter_old) return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_PROFILE, NULL, "Metering is not supported."); @@ -245,17 +245,23 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev, static inline void mlx5_flow_meter_xir_man_exp_calc(int64_t xir, uint8_t *man, uint8_t *exp) { - int64_t _cir; + int64_t _xir; int64_t delta = INT64_MAX; uint8_t _man = 0; uint8_t _exp = 0; uint64_t m, e; + /* Special case xir == 0 ? both exp and mantissa are 0. */ + if (xir == 0) { + *man = 0; + *exp = 0; + return; + } 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(xir - _cir) <= delta) { - delta = llabs(xir - _cir); + _xir = (1000000000ULL * m) >> e; + if (llabs(xir - _xir) <= delta) { + delta = llabs(xir - _xir); _man = m; _exp = e; } @@ -281,7 +287,7 @@ mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp) int _exp; double _man; - /* Special case xbs == 0 ? both exp and matissa are 0. */ + /* Special case xbs == 0 ? both exp and mantissa are 0. */ if (xbs == 0) { *man = 0; *exp = 0; @@ -289,8 +295,10 @@ mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp) } /* xbs = xbs_mantissa * 2^xbs_exponent */ _man = frexp(xbs, &_exp); - _man = _man * pow(2, MLX5_MAN_WIDTH); - _exp = _exp - MLX5_MAN_WIDTH; + if (_exp >= MLX5_MAN_WIDTH) { + _man = _man * pow(2, MLX5_MAN_WIDTH); + _exp = _exp - MLX5_MAN_WIDTH; + } *man = (uint8_t)ceil(_man); *exp = _exp; } @@ -299,7 +307,7 @@ mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp) * Fill the prm meter parameter. * * @param[in,out] fmp - * Pointer to meter profie to be converted. + * Pointer to meter profile to be converted. * @param[out] error * Pointer to the error structure. * @@ -420,7 +428,7 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, struct rte_mtr_error *error __rte_unused) { struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_hca_qos_attr *qattr = &priv->config.hca_attr.qos; + struct mlx5_hca_qos_attr *qattr = &priv->sh->cdev->config.hca_attr.qos; if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, @@ -431,11 +439,14 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, /* 2 meters per one ASO cache line. */ cap->n_max = 1 << (qattr->log_max_num_meter_aso + 1); cap->srtcm_rfc2697_packet_mode_supported = 1; + cap->trtcm_rfc2698_packet_mode_supported = 1; + cap->trtcm_rfc4115_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->trtcm_rfc2698_byte_mode_supported = 1; + cap->trtcm_rfc4115_byte_mode_supported = 1; cap->n_shared_max = cap->n_max; cap->identical = 1; cap->shared_identical = 1; @@ -443,7 +454,10 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, /* 2M flows can share the same meter. */ cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */ cap->meter_srtcm_rfc2697_n_max = qattr->flow_meter_old ? cap->n_max : 0; + cap->meter_trtcm_rfc2698_n_max = qattr->flow_meter_old ? cap->n_max : 0; + cap->meter_trtcm_rfc4115_n_max = qattr->flow_meter_old ? cap->n_max : 0; cap->meter_rate_max = 1ULL << 40; /* 1 Tera tokens per sec. */ + cap->meter_policy_n_max = cap->n_max; cap->stats_mask = RTE_MTR_STATS_N_BYTES_DROPPED | RTE_MTR_STATS_N_PKTS_DROPPED; return 0; @@ -644,8 +658,8 @@ mlx5_flow_meter_policy_validate(struct rte_eth_dev *dev, struct rte_mtr_error *error) { struct mlx5_priv *priv = dev->data->dev_private; - struct rte_flow_attr attr = { .transfer = - priv->config.dv_esw_en ? 1 : 0}; + struct rte_flow_attr attr = { .transfer = priv->sh->config.dv_esw_en ? + 1 : 0 }; bool is_rss = false; uint8_t policy_mode; uint8_t domain_bitmap; @@ -732,8 +746,8 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev, struct rte_mtr_error *error) { struct mlx5_priv *priv = dev->data->dev_private; - struct rte_flow_attr attr = { .transfer = - priv->config.dv_esw_en ? 1 : 0}; + struct rte_flow_attr attr = { .transfer = priv->sh->config.dv_esw_en ? + 1 : 0 }; uint32_t sub_policy_idx = 0; uint32_t policy_idx = 0; struct mlx5_flow_meter_policy *mtr_policy = NULL; @@ -1095,7 +1109,7 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv, if (ret) return ret; } - /* Update succeedded modify meter parameters. */ + /* Update succeeded modify meter parameters. */ if (modify_bits & MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE) fm->active_state = !!active_state; } @@ -1161,7 +1175,8 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, struct mlx5_legacy_flow_meters *fms = &priv->flow_meters; struct mlx5_flow_meter_profile *fmp; struct mlx5_flow_meter_info *fm; - struct mlx5_legacy_flow_meter *legacy_fm; + /* GCC fails to infer legacy_fm is set when !priv->sh->meter_aso_en. */ + struct mlx5_legacy_flow_meter *legacy_fm = NULL; struct mlx5_flow_meter_policy *mtr_policy = NULL; struct mlx5_indexed_pool_config flow_ipool_cfg = { .size = 0, @@ -1198,7 +1213,7 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, (&priv->sh->mtrmng->def_policy_ref_cnt, 1, __ATOMIC_RELAXED); domain_bitmap = MLX5_MTR_ALL_DOMAIN_BIT; - if (!priv->config.dv_esw_en) + if (!priv->sh->config.dv_esw_en) domain_bitmap &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT; } else { if (!priv->sh->meter_aso_en) @@ -1267,8 +1282,10 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, if (mlx5_flow_create_mtr_tbls(dev, fm, mtr_idx, domain_bitmap)) goto error; /* Add to the flow meter list. */ - if (!priv->sh->meter_aso_en) + if (!priv->sh->meter_aso_en) { + MLX5_ASSERT(legacy_fm != NULL); TAILQ_INSERT_TAIL(fms, legacy_fm, next); + } /* Add to the flow meter list. */ fm->active_state = 1; /* Config meter starts as active. */ fm->is_enable = 1; @@ -1609,7 +1626,7 @@ mlx5_flow_meter_profile_update(struct rte_eth_dev *dev, return -rte_mtr_error_set(error, -ret, RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL, "Failed to update meter" - " parmeters in hardware."); + " parameters in hardware."); } old_fmp->ref_cnt--; fmp->ref_cnt++; @@ -1709,7 +1726,7 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, memset(stats, 0, sizeof(*stats)); if (fm->drop_cnt) { ret = mlx5_counter_query(dev, fm->drop_cnt, clear, &pkts, - &bytes); + &bytes, NULL); if (ret) goto error; /* If need to read the packets, set it. */ @@ -1783,24 +1800,21 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id, struct mlx5_aso_mtr_pools_mng *pools_mng = &priv->sh->mtrmng->pools_mng; union mlx5_l3t_data data; + uint16_t n_valid; if (priv->sh->meter_aso_en) { - rte_spinlock_lock(&pools_mng->mtrsl); - if (!pools_mng->n_valid || !priv->mtr_idx_tbl) { - rte_spinlock_unlock(&pools_mng->mtrsl); + rte_rwlock_read_lock(&pools_mng->resize_mtrwl); + n_valid = pools_mng->n_valid; + rte_rwlock_read_unlock(&pools_mng->resize_mtrwl); + if (!n_valid || !priv->mtr_idx_tbl || + (mlx5_l3t_get_entry(priv->mtr_idx_tbl, meter_id, &data) || + !data.dword)) return NULL; - } - if (mlx5_l3t_get_entry(priv->mtr_idx_tbl, meter_id, &data) || - !data.dword) { - rte_spinlock_unlock(&pools_mng->mtrsl); - return NULL; - } if (mtr_idx) *mtr_idx = data.dword; aso_mtr = mlx5_aso_meter_by_idx(priv, data.dword); /* Remove reference taken by the mlx5_l3t_get_entry. */ mlx5_l3t_clear_entry(priv->mtr_idx_tbl, meter_id); - rte_spinlock_unlock(&pools_mng->mtrsl); if (!aso_mtr || aso_mtr->state == ASO_METER_FREE) return NULL; return &aso_mtr->fm; @@ -2162,7 +2176,7 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) priv->mtr_idx_tbl = NULL; } } else { - TAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) { + RTE_TAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) { fm = &legacy_fm->fm; if (mlx5_flow_meter_params_flush(dev, fm, 0)) return -rte_mtr_error_set(error, EINVAL,