From: Suanming Mou Date: Fri, 8 Nov 2019 03:49:19 +0000 (+0200) Subject: net/mlx5: add count action to meter X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4dedc7c639d564a87295228256383d9383f9b858;p=dpdk.git net/mlx5: add count action to meter Add count action to meter for metering packet statistics. All the packets be colored and dropped will be recorded. Signed-off-by: Suanming Mou Acked-by: Matan Azrad --- diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 750e58edf1..ee964b057b 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -4916,17 +4916,20 @@ mlx5_dev_filter_ctrl(struct rte_eth_dev *dev, * * @param[in] dev * Pointer to Ethernet device. + * @param[in] fm + * Pointer to the flow meter. * * @return * Pointer to table set on success, NULL otherwise. */ struct mlx5_meter_domains_infos * -mlx5_flow_create_mtr_tbls(struct rte_eth_dev *dev) +mlx5_flow_create_mtr_tbls(struct rte_eth_dev *dev, + const struct mlx5_flow_meter *fm) { const struct mlx5_flow_driver_ops *fops; fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV); - return fops->create_mtr_tbls(dev); + return fops->create_mtr_tbls(dev, fm); } /** diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 0326330e96..cdcca7ad16 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -531,6 +531,14 @@ struct mlx5_flow { /* Modify this value if enum rte_mtr_color changes. */ #define RTE_MTR_DROPPED RTE_COLORS +/* Meter policer statistics */ +struct mlx5_flow_policer_stats { + struct mlx5_flow_counter *cnt[RTE_COLORS + 1]; + /**< Color counter, extra for drop. */ + uint64_t stats_mask; + /**< Statistics mask for the colors. */ +}; + /* Meter table structure. */ struct mlx5_meter_domain_info { struct mlx5_flow_tbl_resource *tbl; @@ -557,6 +565,8 @@ struct mlx5_meter_domains_infos { /**< FDB meter table. */ void *drop_actn; /**< Drop action as not matched. */ + void *count_actns[RTE_MTR_DROPPED + 1]; + /**< Counters for match and unmatched statistics. */ uint32_t fmp[MLX5_ST_SZ_DW(flow_meter_parameters)]; /**< Flow meter parameter. */ size_t fmp_size; @@ -577,6 +587,8 @@ struct mlx5_flow_meter { /**< Meter profile parameters. */ struct mlx5_meter_domains_infos *mfts; /**< Flow table created for this meter. */ + struct mlx5_flow_policer_stats policer_stats; + /**< Meter policer statistics. */ uint32_t ref_cnt; /**< Use count. */ uint32_t active_state:1; @@ -653,7 +665,8 @@ typedef int (*mlx5_flow_query_t)(struct rte_eth_dev *dev, void *data, struct rte_flow_error *error); typedef struct mlx5_meter_domains_infos *(*mlx5_flow_create_mtr_tbls_t) - (struct rte_eth_dev *dev); + (struct rte_eth_dev *dev, + const struct mlx5_flow_meter *fm); typedef int (*mlx5_flow_destroy_mtr_tbls_t)(struct rte_eth_dev *dev, struct mlx5_meter_domains_infos *tbls); typedef int (*mlx5_flow_create_policer_rules_t) @@ -814,7 +827,8 @@ int mlx5_flow_validate_item_geneve(const struct rte_flow_item *item, struct rte_eth_dev *dev, struct rte_flow_error *error); struct mlx5_meter_domains_infos *mlx5_flow_create_mtr_tbls - (struct rte_eth_dev *dev); + (struct rte_eth_dev *dev, + const struct mlx5_flow_meter *fm); int mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev, struct mlx5_meter_domains_infos *tbl); int mlx5_flow_create_policer_rules(struct rte_eth_dev *dev, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index b273b6c80d..c03950e0d7 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7756,6 +7756,8 @@ flow_dv_prepare_mtr_tables(struct rte_eth_dev *dev, DRV_LOG(ERR, "Failed to create meter policer color matcher."); goto error_exit; } + if (mtb->count_actns[RTE_MTR_DROPPED]) + actions[i++] = mtb->count_actns[RTE_MTR_DROPPED]; actions[i++] = mtb->drop_actn; /* Default rule: lowest priority, match any, actions: drop. */ dtb->policer_rules[RTE_MTR_DROPPED] = @@ -7776,16 +7778,20 @@ error_exit: * * @param[in] dev * Pointer to Ethernet device. + * @param[in] fm + * Pointer to the flow meter. * * @return * Pointer to table set on success, NULL otherwise and rte_errno is set. */ static struct mlx5_meter_domains_infos * -flow_dv_create_mtr_tbl(struct rte_eth_dev *dev) +flow_dv_create_mtr_tbl(struct rte_eth_dev *dev, + const struct mlx5_flow_meter *fm) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_meter_domains_infos *mtb; int ret; + int i; if (!priv->mtr_en) { rte_errno = ENOTSUP; @@ -7796,6 +7802,12 @@ flow_dv_create_mtr_tbl(struct rte_eth_dev *dev) DRV_LOG(ERR, "Failed to allocate memory for meter."); return NULL; } + /* Create meter count actions */ + for (i = 0; i <= RTE_MTR_DROPPED; i++) { + if (!fm->policer_stats.cnt[i]) + continue; + mtb->count_actns[i] = fm->policer_stats.cnt[i]->action; + } /* Create drop action. */ mtb->drop_actn = mlx5_glue->dr_create_flow_action_drop(); if (!mtb->drop_actn) { @@ -7931,6 +7943,8 @@ flow_dv_create_policer_forward_rule(struct mlx5_flow_meter *fm, flow_dv_match_meta_reg(matcher.buf, value.buf, mtr_reg_c, rte_col_2_mlx5_col(i), UINT32_MAX); + if (mtb->count_actns[i]) + actions[j++] = mtb->count_actns[i]; if (fm->params.action[i] == MTR_POLICER_ACTION_DROP) actions[j++] = mtb->drop_actn; else diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index 7f649240c8..7645d9232d 100644 --- a/drivers/net/mlx5/mlx5_flow_meter.c +++ b/drivers/net/mlx5/mlx5_flow_meter.c @@ -571,6 +571,7 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, .transfer = priv->config.dv_esw_en ? 1 : 0, }; int ret; + unsigned int i; if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, @@ -597,7 +598,13 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, fm->meter_id = meter_id; fm->profile = fmp; fm->params = *params; - fm->mfts = mlx5_flow_create_mtr_tbls(dev); + /* Alloc policer counters. */ + for (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++) { + fm->policer_stats.cnt[i] = mlx5_counter_alloc(dev); + if (!fm->policer_stats.cnt[i]) + goto error; + } + fm->mfts = mlx5_flow_create_mtr_tbls(dev, fm); if (!fm->mfts) goto error; ret = mlx5_flow_create_policer_rules(dev, fm, &attr); @@ -612,6 +619,10 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, error: mlx5_flow_destroy_policer_rules(dev, fm, &attr); mlx5_flow_destroy_mtr_tbls(dev, fm->mfts); + /* Free policer counters. */ + for (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++) + if (fm->policer_stats.cnt[i]) + mlx5_counter_free(dev, fm->policer_stats.cnt[i]); rte_free(fm); return -rte_mtr_error_set(error, -ret, RTE_MTR_ERROR_TYPE_UNSPECIFIED, @@ -644,6 +655,7 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, .egress = 1, .transfer = priv->config.dv_esw_en ? 1 : 0, }; + unsigned int i; if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, @@ -667,6 +679,10 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, fmp->ref_cnt--; /* Remove from the flow meter list. */ TAILQ_REMOVE(fms, fm, next); + /* Free policer counters. */ + for (i = 0; i < RTE_DIM(fm->policer_stats.cnt); i++) + if (fm->policer_stats.cnt[i]) + mlx5_counter_free(dev, fm->policer_stats.cnt[i]); /* Free meter flow table */ mlx5_flow_destroy_policer_rules(dev, fm, &attr); mlx5_flow_destroy_mtr_tbls(dev, fm->mfts);