X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_flow_meter.c;h=af0a1c18cb16cfe778379068b64848220ddca284;hb=5f0d54f372f069275a998057cc5e5ef24b543251;hp=714b382d55dc540f069a06e4baab6f30ed1b2803;hpb=fa1d598844a73765cf26676ce3d219589ba57114;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index 714b382d55..af0a1c18cb 100644 --- a/drivers/net/mlx5/mlx5_flow_meter.c +++ b/drivers/net/mlx5/mlx5_flow_meter.c @@ -329,7 +329,6 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, 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_rate_max = 1ULL << 40; /* 1 Tera tokens per sec. */ - cap->policer_action_drop_supported = 1; cap->stats_mask = RTE_MTR_STATS_N_BYTES_DROPPED | RTE_MTR_STATS_N_PKTS_DROPPED; return 0; @@ -436,90 +435,6 @@ mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev, return 0; } -/** - * Convert wrong color setting action to verbose error. - * - * @param[in] action - * Policy color action. - * - * @return - * Verbose meter color error type. - */ -static inline enum rte_mtr_error_type -action2error(enum rte_mtr_policer_action action) -{ - switch (action) { - case MTR_POLICER_ACTION_COLOR_GREEN: - return RTE_MTR_ERROR_TYPE_POLICER_ACTION_GREEN; - case MTR_POLICER_ACTION_COLOR_YELLOW: - return RTE_MTR_ERROR_TYPE_POLICER_ACTION_YELLOW; - case MTR_POLICER_ACTION_COLOR_RED: - return RTE_MTR_ERROR_TYPE_POLICER_ACTION_RED; - default: - break; - } - return RTE_MTR_ERROR_TYPE_UNSPECIFIED; -} - -/** - * Check meter validation. - * - * @param[in] priv - * Pointer to mlx5 private data structure. - * @param[in] meter_id - * Meter id. - * @param[in] params - * Pointer to rte meter parameters. - * @param[out] error - * Pointer to rte meter error structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id, - struct rte_mtr_params *params, - struct rte_mtr_error *error) -{ - /* Meter must use global drop action. */ - if (!priv->sh->dr_drop_action) - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_MTR_PARAMS, - NULL, - "No drop action ready for meter."); - /* Meter params must not be NULL. */ - if (params == NULL) - return -rte_mtr_error_set(error, EINVAL, - RTE_MTR_ERROR_TYPE_MTR_PARAMS, - NULL, "Meter object params null."); - /* Previous meter color is not supported. */ - if (params->use_prev_mtr_color) - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_MTR_PARAMS, - NULL, - "Previous meter color " - "not supported."); - /* Validate policer settings. */ - if (params->action[RTE_COLOR_RED] != MTR_POLICER_ACTION_DROP) - return -rte_mtr_error_set - (error, ENOTSUP, - action2error(params->action[RTE_COLOR_RED]), - NULL, - "Red color only supports drop action."); - if (params->action[RTE_COLOR_GREEN] != MTR_POLICER_ACTION_COLOR_GREEN) - return -rte_mtr_error_set - (error, ENOTSUP, - action2error(params->action[RTE_COLOR_GREEN]), - NULL, - "Green color only supports recolor green action."); - /* Validate meter id. */ - if (mlx5_flow_meter_find(priv, meter_id, NULL)) - return -rte_mtr_error_set(error, EEXIST, - RTE_MTR_ERROR_TYPE_MTR_ID, NULL, - "Meter object already exists."); - return 0; -} - /** * Modify the flow meter action. * @@ -629,167 +544,14 @@ static void mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter_info *fm, uint64_t stats_mask) { - fm->green_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_GREEN) ? 1 : 0; - fm->green_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_GREEN) ? 1 : 0; - fm->red_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_RED) ? 1 : 0; - fm->red_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_RED) ? 1 : 0; fm->bytes_dropped = (stats_mask & RTE_MTR_STATS_N_BYTES_DROPPED) ? 1 : 0; fm->pkts_dropped = (stats_mask & RTE_MTR_STATS_N_PKTS_DROPPED) ? 1 : 0; } -/** - * Create meter rules. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] meter_id - * Meter id. - * @param[in] params - * Pointer to rte meter parameters. - * @param[in] shared - * Meter shared with other flow or not. - * @param[out] error - * Pointer to rte meter error structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, - struct rte_mtr_params *params, int shared, - struct rte_mtr_error *error) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_legacy_flow_meters *fms = &priv->flow_meters; - struct mlx5_flow_meter_profile *fmp; - struct mlx5_legacy_flow_meter *legacy_fm; - struct mlx5_flow_meter_info *fm; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; - struct mlx5_indexed_pool_config flow_ipool_cfg = { - .size = 0, - .trunk_size = 64, - .need_lock = 1, - .type = "mlx5_flow_mtr_flow_id_pool", - }; - struct mlx5_aso_mtr *aso_mtr; - union mlx5_l3t_data data; - uint32_t mtr_idx; - int ret; - uint8_t mtr_id_bits; - uint8_t mtr_reg_bits = priv->mtr_reg_share ? - MLX5_MTR_IDLE_BITS_IN_COLOR_REG : MLX5_REG_BITS; - - if (!priv->mtr_en) - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Meter is not supported"); - /* Validate the parameters. */ - ret = mlx5_flow_meter_validate(priv, meter_id, params, error); - if (ret) - return ret; - /* Meter profile must exist. */ - fmp = mlx5_flow_meter_profile_find(priv, params->meter_profile_id); - if (fmp == NULL) - return -rte_mtr_error_set(error, ENOENT, - RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, - NULL, "Meter profile id not valid."); - /* Allocate the flow meter memory. */ - if (priv->sh->meter_aso_en) { - mtr_idx = mlx5_flow_mtr_alloc(dev); - if (!mtr_idx) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Memory alloc failed for meter."); - aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx); - fm = &aso_mtr->fm; - } else { - legacy_fm = mlx5_ipool_zmalloc - (priv->sh->ipool[MLX5_IPOOL_MTR], &mtr_idx); - if (legacy_fm == NULL) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Memory alloc failed for meter."); - legacy_fm->idx = mtr_idx; - fm = &legacy_fm->fm; - } - mtr_id_bits = MLX5_REG_BITS - __builtin_clz(mtr_idx); - if ((mtr_id_bits + priv->max_mtr_flow_bits) > mtr_reg_bits) { - DRV_LOG(ERR, "Meter number exceeds max limit."); - goto error; - } - if (mtr_id_bits > priv->max_mtr_bits) - priv->max_mtr_bits = mtr_id_bits; - /* Fill the flow meter parameters. */ - fm->meter_id = meter_id; - fm->profile = fmp; - memcpy(fm->action, params->action, sizeof(params->action)); - mlx5_flow_meter_stats_enable_update(fm, params->stats_mask); - /* Alloc policer counters. */ - if (fm->green_bytes || fm->green_pkts) { - fm->policer_stats.pass_cnt = mlx5_counter_alloc(dev); - if (!fm->policer_stats.pass_cnt) - goto error; - } - if (fm->red_bytes || fm->red_pkts || - fm->bytes_dropped || fm->pkts_dropped) { - fm->policer_stats.drop_cnt = mlx5_counter_alloc(dev); - if (!fm->policer_stats.drop_cnt) - goto error; - } - fm->mfts = mlx5_flow_create_mtr_tbls(dev); - if (!fm->mfts) - goto error; - ret = mlx5_flow_prepare_policer_rules(dev, fm, &attr); - if (ret) - goto error; - /* Add to the flow meter list. */ - if (!priv->sh->meter_aso_en) - TAILQ_INSERT_TAIL(fms, legacy_fm, next); - fm->active_state = 1; /* Config meter starts as active. */ - fm->is_enable = 1; - fm->shared = !!shared; - __atomic_add_fetch(&fm->profile->ref_cnt, 1, __ATOMIC_RELAXED); - fm->flow_ipool = mlx5_ipool_create(&flow_ipool_cfg); - if (!fm->flow_ipool) - goto error; - rte_spinlock_init(&fm->sl); - /* If ASO meter supported, allocate ASO flow meter. */ - if (priv->sh->meter_aso_en) { - aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm); - ret = mlx5_aso_meter_update_by_wqe(priv->sh, aso_mtr); - if (ret) - goto error; - data.dword = mtr_idx; - if (mlx5_l3t_set_entry(priv->mtr_idx_tbl, meter_id, &data)) - goto error; - } - return 0; -error: - mlx5_flow_destroy_policer_rules(dev, fm, &attr); - mlx5_flow_destroy_mtr_tbls(dev, fm->mfts); - /* Free policer counters. */ - if (fm->policer_stats.pass_cnt) - mlx5_counter_free(dev, fm->policer_stats.pass_cnt); - if (fm->policer_stats.drop_cnt) - mlx5_counter_free(dev, fm->policer_stats.drop_cnt); - if (priv->sh->meter_aso_en) - mlx5_flow_mtr_free(dev, mtr_idx); - else - mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], mtr_idx); - return -rte_mtr_error_set(error, -ret, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, - NULL, "Failed to create devx meter."); -} - static int mlx5_flow_meter_params_flush(struct rte_eth_dev *dev, struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr, uint32_t mtr_idx) { struct mlx5_priv *priv = dev->data->dev_private; @@ -810,15 +572,12 @@ mlx5_flow_meter_params_flush(struct rte_eth_dev *dev, legacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm); TAILQ_REMOVE(fms, legacy_fm, next); } - /* Free policer counters. */ - if (fm->policer_stats.pass_cnt) - mlx5_counter_free(dev, fm->policer_stats.pass_cnt); - if (fm->policer_stats.drop_cnt) - mlx5_counter_free(dev, fm->policer_stats.drop_cnt); + /* Free drop counters. */ + if (fm->drop_cnt) + mlx5_counter_free(dev, fm->drop_cnt); /* Free meter flow table. */ if (fm->flow_ipool) mlx5_ipool_destroy(fm->flow_ipool); - mlx5_flow_destroy_policer_rules(dev, fm, attr); mlx5_flow_destroy_mtr_tbls(dev, fm->mfts); if (priv->sh->meter_aso_en) mlx5_flow_mtr_free(dev, mtr_idx); @@ -847,11 +606,6 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_info *fm; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; uint32_t mtr_idx = 0; if (!priv->mtr_en) @@ -876,7 +630,7 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, "Fail to delete ASO Meter in index table."); } /* Destroy the meter profile. */ - if (mlx5_flow_meter_params_flush(dev, fm, &attr, mtr_idx)) + if (mlx5_flow_meter_params_flush(dev, fm, mtr_idx)) return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL, "MTR object meter profile invalid."); @@ -1102,13 +856,6 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev, { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_info *fm; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; - bool need_updated = false; - struct mlx5_flow_policer_stats old_policer_stats; if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, @@ -1120,69 +867,6 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev, return -rte_mtr_error_set(error, ENOENT, RTE_MTR_ERROR_TYPE_MTR_ID, NULL, "Meter object id not valid."); - old_policer_stats.pass_cnt = 0; - old_policer_stats.drop_cnt = 0; - if (!!((RTE_MTR_STATS_N_PKTS_GREEN | - RTE_MTR_STATS_N_BYTES_GREEN) & stats_mask) != - !!fm->policer_stats.pass_cnt) { - need_updated = true; - if (fm->policer_stats.pass_cnt) { - old_policer_stats.pass_cnt = fm->policer_stats.pass_cnt; - fm->policer_stats.pass_cnt = 0; - } else { - fm->policer_stats.pass_cnt = - mlx5_counter_alloc(dev); - if (!fm->policer_stats.pass_cnt) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Counter alloc failed for meter."); - } - } - if (!!((RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_BYTES_RED | - RTE_MTR_STATS_N_PKTS_DROPPED | RTE_MTR_STATS_N_BYTES_DROPPED) & - stats_mask) != - !!fm->policer_stats.drop_cnt) { - need_updated = true; - if (fm->policer_stats.drop_cnt) { - old_policer_stats.drop_cnt = fm->policer_stats.drop_cnt; - fm->policer_stats.drop_cnt = 0; - } else { - fm->policer_stats.drop_cnt = - mlx5_counter_alloc(dev); - if (!fm->policer_stats.drop_cnt) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Counter alloc failed for meter."); - } - } - if (need_updated) { - if (mlx5_flow_prepare_policer_rules(dev, fm, &attr)) { - if (fm->policer_stats.pass_cnt && - fm->policer_stats.pass_cnt != - old_policer_stats.pass_cnt) - mlx5_counter_free(dev, - fm->policer_stats.pass_cnt); - fm->policer_stats.pass_cnt = - old_policer_stats.pass_cnt; - if (fm->policer_stats.drop_cnt && - fm->policer_stats.drop_cnt != - old_policer_stats.drop_cnt) - mlx5_counter_free(dev, - fm->policer_stats.drop_cnt); - fm->policer_stats.pass_cnt = - old_policer_stats.pass_cnt; - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, - NULL, "Failed to create meter policer rules."); - } - /* Free old policer counters. */ - if (old_policer_stats.pass_cnt) - mlx5_counter_free(dev, - old_policer_stats.pass_cnt); - if (old_policer_stats.drop_cnt) - mlx5_counter_free(dev, - old_policer_stats.drop_cnt); - } mlx5_flow_meter_stats_enable_update(fm, stats_mask); return 0; } @@ -1216,7 +900,6 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_info *fm; - struct mlx5_flow_policer_stats *ps; uint64_t pkts; uint64_t bytes; int ret = 0; @@ -1231,35 +914,14 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, return -rte_mtr_error_set(error, ENOENT, RTE_MTR_ERROR_TYPE_MTR_ID, NULL, "Meter object id not valid."); - ps = &fm->policer_stats; *stats_mask = 0; - if (fm->green_bytes) - *stats_mask |= RTE_MTR_STATS_N_BYTES_GREEN; - if (fm->green_pkts) - *stats_mask |= RTE_MTR_STATS_N_PKTS_GREEN; - if (fm->red_bytes) - *stats_mask |= RTE_MTR_STATS_N_BYTES_RED; - if (fm->red_pkts) - *stats_mask |= RTE_MTR_STATS_N_PKTS_RED; if (fm->bytes_dropped) *stats_mask |= RTE_MTR_STATS_N_BYTES_DROPPED; if (fm->pkts_dropped) *stats_mask |= RTE_MTR_STATS_N_PKTS_DROPPED; memset(stats, 0, sizeof(*stats)); - if (ps->pass_cnt) { - ret = mlx5_counter_query(dev, ps->pass_cnt, clear, &pkts, - &bytes); - if (ret) - goto error; - /* If need to read the packets, set it. */ - if (fm->green_pkts) - stats->n_pkts[RTE_COLOR_GREEN] = pkts; - /* If need to read the bytes, set it. */ - if (fm->green_bytes) - stats->n_bytes[RTE_COLOR_GREEN] = bytes; - } - if (ps->drop_cnt) { - ret = mlx5_counter_query(dev, ps->drop_cnt, clear, &pkts, + if (fm->drop_cnt) { + ret = mlx5_counter_query(dev, fm->drop_cnt, clear, &pkts, &bytes); if (ret) goto error; @@ -1273,20 +935,18 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, return 0; error: return -rte_mtr_error_set(error, ret, RTE_MTR_ERROR_TYPE_STATS, NULL, - "Failed to read policer counters."); + "Failed to read meter drop counters."); } static const struct rte_mtr_ops mlx5_flow_mtr_ops = { .capabilities_get = mlx5_flow_mtr_cap_get, .meter_profile_add = mlx5_flow_meter_profile_add, .meter_profile_delete = mlx5_flow_meter_profile_delete, - .create = mlx5_flow_meter_create, .destroy = mlx5_flow_meter_destroy, .meter_enable = mlx5_flow_meter_enable, .meter_disable = mlx5_flow_meter_disable, .meter_profile_update = mlx5_flow_meter_profile_update, .meter_dscp_table_update = NULL, - .policer_actions_update = NULL, .stats_update = mlx5_flow_meter_stats_update, .stats_read = mlx5_flow_meter_stats_read, }; @@ -1344,12 +1004,11 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id, 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); - MLX5_ASSERT(meter_id == aso_mtr->fm.meter_id); rte_spinlock_unlock(&mtrmng->mtrsl); return &aso_mtr->fm; } TAILQ_FOREACH(legacy_fm, fms, next) - if (meter_id == legacy_fm->fm.meter_id) { + if (meter_id == legacy_fm->meter_id) { if (mtr_idx) *mtr_idx = legacy_fm->idx; return &legacy_fm->fm; @@ -1517,11 +1176,6 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) struct mlx5_legacy_flow_meter *legacy_fm; struct mlx5_flow_meter_info *fm; struct mlx5_aso_mtr_pool *mtr_pool; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; void *tmp; uint32_t i, offset, mtr_idx; @@ -1533,9 +1187,8 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) offset++) { fm = &mtr_pool->mtrs[offset].fm; mtr_idx = MLX5_MAKE_MTR_IDX(i, offset); - if (fm->meter_id != UINT32_MAX && - mlx5_flow_meter_params_flush(dev, - fm, &attr, mtr_idx)) + if (mlx5_flow_meter_params_flush(dev, + fm, mtr_idx)) return -rte_mtr_error_set (error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, @@ -1545,7 +1198,7 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) } else { TAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) { fm = &legacy_fm->fm; - if (mlx5_flow_meter_params_flush(dev, fm, &attr, 0)) + if (mlx5_flow_meter_params_flush(dev, fm, 0)) return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL, "MTR object meter profile invalid.");