From 956d5c74d7863bcdd0de904331661129cb1bf89e Mon Sep 17 00:00:00 2001 From: Suanming Mou Date: Tue, 7 Apr 2020 11:59:45 +0800 Subject: [PATCH] net/mlx5: optimize flow counter handle type Currently, DV and verbs counters are both changed to indexed. It means while creating the flow with counter, flow can save the indexed value to address the counter. Save the 4 bytes indexed value in the rte_flow instead of 8 bytes pointer helps to save memory with millions of flows. Signed-off-by: Suanming Mou Acked-by: Matan Azrad --- drivers/net/mlx5/mlx5.h | 6 ++-- drivers/net/mlx5/mlx5_flow.c | 14 ++++---- drivers/net/mlx5/mlx5_flow.h | 10 +++--- drivers/net/mlx5/mlx5_flow_dv.c | 54 ++++++++++++++---------------- drivers/net/mlx5/mlx5_flow_verbs.c | 36 +++++++++----------- 5 files changed, 56 insertions(+), 64 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index a6cd2b34a0..302566cbdb 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -764,9 +764,9 @@ void mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh, uint64_t async_id, int status); void mlx5_set_query_alarm(struct mlx5_ibv_shared *sh); void mlx5_flow_query_alarm(void *arg); -struct mlx5_flow_counter *mlx5_counter_alloc(struct rte_eth_dev *dev); -void mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt); -int mlx5_counter_query(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt, +uint32_t mlx5_counter_alloc(struct rte_eth_dev *dev); +void mlx5_counter_free(struct rte_eth_dev *dev, uint32_t cnt); +int mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt, bool clear, uint64_t *pkts, uint64_t *bytes); int mlx5_flow_dev_dump(struct rte_eth_dev *dev, FILE *file, struct rte_flow_error *error); diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index d2e9cc4903..3b358b6b8c 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -5494,9 +5494,9 @@ mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev, * Pointer to Ethernet device structure. * * @return - * Pointer to allocated counter on success, NULL otherwise. + * Index to allocated counter on success, 0 otherwise. */ -struct mlx5_flow_counter * +uint32_t mlx5_counter_alloc(struct rte_eth_dev *dev) { const struct mlx5_flow_driver_ops *fops; @@ -5509,7 +5509,7 @@ mlx5_counter_alloc(struct rte_eth_dev *dev) DRV_LOG(ERR, "port %u counter allocate is not supported.", dev->data->port_id); - return NULL; + return 0; } /** @@ -5518,10 +5518,10 @@ mlx5_counter_alloc(struct rte_eth_dev *dev) * @param[in] dev * Pointer to Ethernet device structure. * @param[in] cnt - * Pointer to counter to be free. + * Index to counter to be free. */ void -mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt) +mlx5_counter_free(struct rte_eth_dev *dev, uint32_t cnt) { const struct mlx5_flow_driver_ops *fops; struct rte_flow_attr attr = { .transfer = 0 }; @@ -5542,7 +5542,7 @@ mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt) * @param[in] dev * Pointer to Ethernet device structure. * @param[in] cnt - * Pointer to counter to query. + * Index to counter to query. * @param[in] clear * Set to clear counter statistics. * @param[out] pkts @@ -5554,7 +5554,7 @@ mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt) * 0 on success, a negative errno value otherwise. */ int -mlx5_counter_query(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt, +mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt, bool clear, uint64_t *pkts, uint64_t *bytes) { const struct mlx5_flow_driver_ops *fops; diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 0f0e59dd23..daa1f84145 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -632,7 +632,7 @@ struct mlx5_flow { /* Meter policer statistics */ struct mlx5_flow_policer_stats { - struct mlx5_flow_counter *cnt[RTE_COLORS + 1]; + uint32_t cnt[RTE_COLORS + 1]; /**< Color counter, extra for drop. */ uint64_t stats_mask; /**< Statistics mask for the colors. */ @@ -729,7 +729,7 @@ struct rte_flow { TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */ enum mlx5_flow_drv_type drv_type; /**< Driver type. */ struct mlx5_flow_rss rss; /**< RSS context. */ - struct mlx5_flow_counter *counter; /**< Holds flow counter. */ + uint32_t counter; /**< Holds flow counter. */ struct mlx5_flow_mreg_copy_resource *mreg_copy; /**< pointer to metadata register copy table resource. */ struct mlx5_flow_meter *meter; /**< Holds flow meter. */ @@ -780,12 +780,12 @@ typedef int (*mlx5_flow_destroy_policer_rules_t) (struct rte_eth_dev *dev, const struct mlx5_flow_meter *fm, const struct rte_flow_attr *attr); -typedef struct mlx5_flow_counter * (*mlx5_flow_counter_alloc_t) +typedef uint32_t (*mlx5_flow_counter_alloc_t) (struct rte_eth_dev *dev); typedef void (*mlx5_flow_counter_free_t)(struct rte_eth_dev *dev, - struct mlx5_flow_counter *cnt); + uint32_t cnt); typedef int (*mlx5_flow_counter_query_t)(struct rte_eth_dev *dev, - struct mlx5_flow_counter *cnt, + uint32_t cnt, bool clear, uint64_t *pkts, uint64_t *bytes); struct mlx5_flow_driver_ops { diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 955f43b00f..9032d5028e 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3892,7 +3892,7 @@ flow_dv_counter_alloc_fallback(struct rte_eth_dev *dev, uint32_t shared, * @param[in] dev * Pointer to the Ethernet device structure. * @param[in] counter - * Pointer to the counter handler. + * Index to the counter handler. */ static void flow_dv_counter_release_fallback(struct rte_eth_dev *dev __rte_unused, @@ -4384,9 +4384,9 @@ flow_dv_counter_shared_search(struct mlx5_pools_container *cont, uint32_t id, * Counter flow group. * * @return - * pointer to flow counter on success, NULL otherwise and rte_errno is set. + * Index to flow counter on success, 0 otherwise and rte_errno is set. */ -static struct mlx5_flow_counter * +static uint32_t flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, uint16_t group) { @@ -4408,24 +4408,24 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, if (!priv->config.devx) { rte_errno = ENOTSUP; - return NULL; + return 0; } if (shared) { cnt_free = flow_dv_counter_shared_search(cont, id, &pool); if (cnt_free) { if (cnt_free->ref_cnt + 1 == 0) { rte_errno = E2BIG; - return NULL; + return 0; } cnt_free->ref_cnt++; cnt_idx = pool->index * MLX5_COUNTERS_PER_POOL + (cnt_free - pool->counters_raw) + 1; - return (struct mlx5_flow_counter *)(uintptr_t)cnt_idx; + return cnt_idx; } } if (priv->counter_fallback) - return (struct mlx5_flow_counter *)(uintptr_t) - flow_dv_counter_alloc_fallback(dev, shared, id); + return flow_dv_counter_alloc_fallback(dev, shared, id); + /* Pools which has a free counters are in the start. */ TAILQ_FOREACH(pool, &cont->pool_list, next) { /* @@ -4446,7 +4446,7 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, if (!cnt_free) { cont = flow_dv_counter_pool_prepare(dev, &cnt_free, batch); if (!cont) - return NULL; + return 0; pool = TAILQ_FIRST(&cont->pool_list); } cnt_free->batch = batch; @@ -4466,13 +4466,13 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, (dcs->obj, offset); if (!cnt_free->action) { rte_errno = errno; - return NULL; + return 0; } } /* Update the counter reset values. */ if (_flow_dv_query_count(dev, cnt_free, &cnt_free->hits, &cnt_free->bytes)) - return NULL; + return 0; cnt_free->shared = shared; cnt_free->ref_cnt = 1; cnt_free->id = id; @@ -4488,7 +4488,7 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, cnt_idx = MLX5_MAKE_CNT_IDX(pool->index, (cnt_free - pool->counters_raw)); cnt_idx += batch * MLX5_CNT_BATCH_OFFSET; - return (struct mlx5_flow_counter *)(uintptr_t)cnt_idx; + return cnt_idx; } /** @@ -4497,11 +4497,10 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, * @param[in] dev * Pointer to the Ethernet device structure. * @param[in] counter - * Pointer to the counter handler. + * Index to the counter handler. */ static void -flow_dv_counter_release(struct rte_eth_dev *dev, - struct mlx5_flow_counter *counter) +flow_dv_counter_release(struct rte_eth_dev *dev, uint32_t counter) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_counter_pool *pool; @@ -4509,7 +4508,7 @@ flow_dv_counter_release(struct rte_eth_dev *dev, if (!counter) return; - cnt = flow_dv_counter_get_by_idx(dev, (uintptr_t)counter, &pool); + cnt = flow_dv_counter_get_by_idx(dev, counter, &pool); if (priv->counter_fallback) { flow_dv_counter_release_fallback(dev, cnt); return; @@ -7588,11 +7587,11 @@ __flow_dv_translate(struct rte_eth_dev *dev, count->shared, count->id, dev_flow->dv.group); - if (flow->counter == NULL) + if (!flow->counter) goto cnt_err; dev_flow->dv.actions[actions_n++] = (flow_dv_counter_get_by_idx(dev, - (uintptr_t)flow->counter, NULL))->action; + flow->counter, NULL))->action; action_flags |= MLX5_FLOW_ACTION_COUNT; break; cnt_err: @@ -8465,7 +8464,7 @@ __flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) __flow_dv_remove(dev, flow); if (flow->counter) { flow_dv_counter_release(dev, flow->counter); - flow->counter = NULL; + flow->counter = 0; } if (flow->meter) { mlx5_flow_meter_detach(flow->meter); @@ -8524,7 +8523,7 @@ flow_dv_query_count(struct rte_eth_dev *dev, struct rte_flow *flow, uint64_t pkts, bytes; struct mlx5_flow_counter *cnt; - cnt = flow_dv_counter_get_by_idx(dev, (uintptr_t)flow->counter, + cnt = flow_dv_counter_get_by_idx(dev, flow->counter, NULL); int err = _flow_dv_query_count(dev, cnt, &pkts, &bytes); @@ -8793,7 +8792,7 @@ flow_dv_create_mtr_tbl(struct rte_eth_dev *dev, if (!fm->policer_stats.cnt[i]) continue; cnt = flow_dv_counter_get_by_idx(dev, - (uintptr_t)fm->policer_stats.cnt[i], NULL); + fm->policer_stats.cnt[i], NULL); mtb->count_actns[i] = cnt->action; } /* Create drop action. */ @@ -9013,7 +9012,7 @@ error: * @param[in] dev * Pointer to the Ethernet device structure. * @param[in] cnt - * Pointer to the flow counter. + * Index to the flow counter. * @param[in] clear * Set to clear the counter statistics. * @param[out] pkts @@ -9025,8 +9024,7 @@ error: * 0 on success, otherwise return -1. */ static int -flow_dv_counter_query(struct rte_eth_dev *dev, - struct mlx5_flow_counter *counter, bool clear, +flow_dv_counter_query(struct rte_eth_dev *dev, uint32_t counter, bool clear, uint64_t *pkts, uint64_t *bytes) { struct mlx5_priv *priv = dev->data->dev_private; @@ -9037,7 +9035,7 @@ flow_dv_counter_query(struct rte_eth_dev *dev, if (!priv->config.devx) return -1; - cnt = flow_dv_counter_get_by_idx(dev, (uintptr_t)counter, NULL); + cnt = flow_dv_counter_get_by_idx(dev, counter, NULL); ret = _flow_dv_query_count(dev, cnt, &inn_pkts, &inn_bytes); if (ret) return -1; @@ -9110,10 +9108,10 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) /* * Mutex-protected thunk to lock-free flow_dv_counter_alloc(). */ -static struct mlx5_flow_counter * +static uint32_t flow_dv_counter_allocate(struct rte_eth_dev *dev) { - struct mlx5_flow_counter *cnt; + uint32_t cnt; flow_dv_shared_lock(dev); cnt = flow_dv_counter_alloc(dev, 0, 0, 1); @@ -9125,7 +9123,7 @@ flow_dv_counter_allocate(struct rte_eth_dev *dev) * Mutex-protected thunk to lock-free flow_dv_counter_release(). */ static void -flow_dv_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt) +flow_dv_counter_free(struct rte_eth_dev *dev, uint32_t cnt) { flow_dv_shared_lock(dev); flow_dv_counter_release(dev, cnt); diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index f1489f1195..576334abd6 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -145,9 +145,9 @@ flow_verbs_counter_create(struct rte_eth_dev *dev, * Counter identifier. * * @return - * A pointer to the counter, NULL otherwise and rte_errno is set. + * Index to the counter, 0 otherwise and rte_errno is set. */ -static struct mlx5_flow_counter * +static uint32_t flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) { struct mlx5_priv *priv = dev->data->dev_private; @@ -166,9 +166,7 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) cnt = &pool->counters_raw[i]; if (cnt->shared && cnt->id == id) { cnt->ref_cnt++; - return (struct mlx5_flow_counter *) - (uintptr_t) - MLX5_MAKE_CNT_IDX(pool_idx, i); + return MLX5_MAKE_CNT_IDX(pool_idx, i); } } } @@ -191,7 +189,7 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) (n_valid + MLX5_CNT_CONTAINER_RESIZE); pools = rte_zmalloc(__func__, size, 0); if (!pools) - return NULL; + return 0; if (n_valid) { memcpy(pools, cont->pools, sizeof(struct mlx5_flow_counter_pool *) * @@ -205,7 +203,7 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) size = sizeof(*pool) + sizeof(*cnt) * MLX5_COUNTERS_PER_POOL; pool = rte_calloc(__func__, 1, size, 0); if (!pool) - return NULL; + return 0; for (i = 0; i < MLX5_COUNTERS_PER_POOL; ++i) { cnt = &pool->counters_raw[i]; TAILQ_INSERT_HEAD(&pool->counters, cnt, next); @@ -225,12 +223,11 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) ret = flow_verbs_counter_create(dev, cnt); if (!ret) { TAILQ_REMOVE(&pool->counters, cnt, next); - return (struct mlx5_flow_counter *)(uintptr_t) - MLX5_MAKE_CNT_IDX(pool_idx, (cnt - pool->counters_raw)); + return MLX5_MAKE_CNT_IDX(pool_idx, (cnt - pool->counters_raw)); } /* Some error occurred in Verbs library. */ rte_errno = -ret; - return NULL; + return 0; } /** @@ -239,18 +236,17 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) * @param[in] dev * Pointer to the Ethernet device structure. * @param[in] counter - * Pointer to the counter handler. + * Index to the counter handler. */ static void -flow_verbs_counter_release(struct rte_eth_dev *dev, - struct mlx5_flow_counter *counter) +flow_verbs_counter_release(struct rte_eth_dev *dev, uint32_t counter) { struct mlx5_flow_counter_pool *pool; struct mlx5_flow_counter *cnt; - cnt = flow_verbs_counter_get_by_idx(dev, (uintptr_t)(void *)counter, + cnt = flow_verbs_counter_get_by_idx(dev, counter, &pool); - if (--counter->ref_cnt == 0) { + if (--cnt->ref_cnt == 0) { #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) claim_zero(mlx5_glue->destroy_counter_set(cnt->cs)); cnt->cs = NULL; @@ -275,10 +271,9 @@ flow_verbs_counter_query(struct rte_eth_dev *dev __rte_unused, { #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) || \ defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) - if (flow->counter && flow->counter->cs) { + if (flow->counter) { struct mlx5_flow_counter *cnt = flow_verbs_counter_get_by_idx - (dev, (uintptr_t)(void *) - flow->counter, NULL); + (dev, flow->counter, NULL); struct rte_flow_query_count *qc = data; uint64_t counters[2] = {0, 0}; #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) @@ -1082,8 +1077,7 @@ flow_verbs_translate_action_count(struct mlx5_flow *dev_flow, "cannot get counter" " context."); } - cnt = flow_verbs_counter_get_by_idx(dev, (uintptr_t)(void *) - flow->counter, NULL); + cnt = flow_verbs_counter_get_by_idx(dev, flow->counter, NULL); #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) counter.counter_set_handle = cnt->cs->handle; flow_verbs_spec_add(&dev_flow->verbs, &counter, size); @@ -1775,7 +1769,7 @@ flow_verbs_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) } if (flow->counter) { flow_verbs_counter_release(dev, flow->counter); - flow->counter = NULL; + flow->counter = 0; } } -- 2.20.1