From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 84CC0A0577; Tue, 7 Apr 2020 06:00:25 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A92591BF54; Tue, 7 Apr 2020 06:00:01 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 6AF6B1BF3C for ; Tue, 7 Apr 2020 05:59:59 +0200 (CEST) From: Suanming Mou To: Matan Azrad , Shahaf Shuler , Viacheslav Ovsiienko Cc: dev@dpdk.org, rasland@mellanox.com Date: Tue, 7 Apr 2020 11:59:42 +0800 Message-Id: <1586231987-338112-4-git-send-email-suanmingm@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1586231987-338112-1-git-send-email-suanmingm@mellanox.com> References: <1586231987-338112-1-git-send-email-suanmingm@mellanox.com> Subject: [dpdk-dev] [PATCH 3/8] net/mlx5: change verbs counter allocator to indexed X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This is part of the counter optimize which will save the indexed counter id instead of the counter pointer in the rte_flow. Place the verbs counter into the container pool helps the counter to be indexed correctly independent with the raw counter. The counter pointer in rte_flow will be changed to indexed value after the DV counter is also changed to indexed. Signed-off-by: Suanming Mou Acked-by: Matan Azrad --- drivers/net/mlx5/mlx5.h | 9 +++ drivers/net/mlx5/mlx5_flow_dv.c | 2 - drivers/net/mlx5/mlx5_flow_verbs.c | 137 ++++++++++++++++++++++++++++++------- 3 files changed, 122 insertions(+), 26 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index fe7e684..6b10dfb 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -238,6 +238,15 @@ struct mlx5_drop { #define MLX5_COUNTERS_PER_POOL 512 #define MLX5_MAX_PENDING_QUERIES 4 +#define MLX5_CNT_CONTAINER_RESIZE 64 +/* + * The pool index and offset of counter in the pool arrary makes up the + * counter index. In case the counter is from pool 0 and offset 0, it + * should plus 1 to avoid index 0, since 0 means invalid counter index + * currently. + */ +#define MLX5_MAKE_CNT_IDX(pi, offset) \ + ((pi) * MLX5_COUNTERS_PER_POOL + (offset) + 1) struct mlx5_flow_counter_pool; diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 074f05f..dc11304 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3820,8 +3820,6 @@ struct field_modify_info modify_tcp[] = { return 0; } -#define MLX5_CNT_CONTAINER_RESIZE 64 - /** * Get or create a flow counter. * diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index ccd3395..c053778 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -38,6 +38,36 @@ (!!((item_flags) & MLX5_FLOW_LAYER_TUNNEL) ? IBV_FLOW_SPEC_INNER : 0) /** + * Get Verbs flow counter by index. + * + * @param[in] dev + * Pointer to the Ethernet device structure. + * @param[in] idx + * mlx5 flow counter index in the container. + * @param[out] ppool + * mlx5 flow counter pool in the container, + * + * @return + * A pointer to the counter, NULL otherwise. + */ +static struct mlx5_flow_counter * +flow_verbs_counter_get_by_idx(struct rte_eth_dev *dev, + uint32_t idx, + struct mlx5_flow_counter_pool **ppool) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv->sh, 0, 0); + struct mlx5_flow_counter_pool *pool; + + idx--; + pool = cont->pools[idx / MLX5_COUNTERS_PER_POOL]; + MLX5_ASSERT(pool); + if (ppool) + *ppool = pool; + return &pool->counters_raw[idx % MLX5_COUNTERS_PER_POOL]; +} + +/** * Create Verbs flow counter with Verbs library. * * @param[in] dev @@ -121,21 +151,70 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id) { struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_flow_counter *cnt; + struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv->sh, 0, 0); + struct mlx5_flow_counter_pool *pool = NULL; + struct mlx5_flow_counter *cnt = NULL; + uint32_t n_valid = rte_atomic16_read(&cont->n_valid); + uint32_t pool_idx; + uint32_t i; int ret; if (shared) { - TAILQ_FOREACH(cnt, &priv->sh->cmng.flow_counters, next) { - if (cnt->shared && cnt->id == id) { - cnt->ref_cnt++; - return cnt; + for (pool_idx = 0; pool_idx < n_valid; ++pool_idx) { + pool = cont->pools[pool_idx]; + for (i = 0; i < MLX5_COUNTERS_PER_POOL; ++i) { + 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); + } } } } - cnt = rte_calloc(__func__, 1, sizeof(*cnt), 0); + for (pool_idx = 0; pool_idx < n_valid; ++pool_idx) { + pool = cont->pools[pool_idx]; + if (!pool) + continue; + cnt = TAILQ_FIRST(&pool->counters); + if (cnt) + break; + } if (!cnt) { - rte_errno = ENOMEM; - return NULL; + struct mlx5_flow_counter_pool **pools; + uint32_t size; + + if (n_valid == cont->n) { + /* Resize the container pool arrary. */ + size = sizeof(struct mlx5_flow_counter_pool *) * + (n_valid + MLX5_CNT_CONTAINER_RESIZE); + pools = rte_zmalloc(__func__, size, 0); + if (!pools) + return NULL; + if (n_valid) { + memcpy(pools, cont->pools, + sizeof(struct mlx5_flow_counter_pool *) * + n_valid); + rte_free(cont->pools); + } + cont->pools = pools; + cont->n += MLX5_CNT_CONTAINER_RESIZE; + } + /* Allocate memory for new pool*/ + size = sizeof(*pool) + sizeof(*cnt) * MLX5_COUNTERS_PER_POOL; + pool = rte_calloc(__func__, 1, size, 0); + if (!pool) + return NULL; + for (i = 0; i < MLX5_COUNTERS_PER_POOL; ++i) { + cnt = &pool->counters_raw[i]; + TAILQ_INSERT_HEAD(&pool->counters, cnt, next); + } + cnt = &pool->counters_raw[0]; + cont->pools[n_valid] = pool; + pool_idx = n_valid; + rte_atomic16_add(&cont->n_valid, 1); + TAILQ_INSERT_HEAD(&cont->pool_list, pool, next); } cnt->id = id; cnt->shared = shared; @@ -145,11 +224,11 @@ /* Create counter with Verbs. */ ret = flow_verbs_counter_create(dev, cnt); if (!ret) { - TAILQ_INSERT_HEAD(&priv->sh->cmng.flow_counters, cnt, next); - return cnt; + TAILQ_REMOVE(&pool->counters, cnt, next); + return (struct mlx5_flow_counter *)(uintptr_t) + MLX5_MAKE_CNT_IDX(pool_idx, (cnt - pool->counters_raw)); } /* Some error occurred in Verbs library. */ - rte_free(cnt); rte_errno = -ret; return NULL; } @@ -166,16 +245,20 @@ flow_verbs_counter_release(struct rte_eth_dev *dev, struct mlx5_flow_counter *counter) { - struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_flow_counter_pool *pool; + struct mlx5_flow_counter *cnt; + cnt = flow_verbs_counter_get_by_idx(dev, (uintptr_t)(void *)counter, + &pool); if (--counter->ref_cnt == 0) { #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) - claim_zero(mlx5_glue->destroy_counter_set(counter->cs)); + claim_zero(mlx5_glue->destroy_counter_set(cnt->cs)); + cnt->cs = NULL; #elif defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) - claim_zero(mlx5_glue->destroy_counters(counter->cs)); + claim_zero(mlx5_glue->destroy_counters(cnt->cs)); + cnt->cs = NULL; #endif - TAILQ_REMOVE(&priv->sh->cmng.flow_counters, counter, next); - rte_free(counter); + TAILQ_INSERT_HEAD(&pool->counters, cnt, next); } } @@ -193,11 +276,14 @@ #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) || \ defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) if (flow->counter && flow->counter->cs) { + struct mlx5_flow_counter *cnt = flow_verbs_counter_get_by_idx + (dev, (uintptr_t)(void *) + flow->counter, NULL); struct rte_flow_query_count *qc = data; uint64_t counters[2] = {0, 0}; #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) struct ibv_query_counter_set_attr query_cs_attr = { - .cs = flow->counter->cs, + .cs = cnt->cs, .query_flags = IBV_COUNTER_SET_FORCE_UPDATE, }; struct ibv_counter_set_data query_out = { @@ -208,7 +294,7 @@ &query_out); #elif defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) int err = mlx5_glue->query_counters - (flow->counter->cs, counters, + (cnt->cs, counters, RTE_DIM(counters), IBV_READ_COUNTERS_ATTR_PREFER_CACHED); #endif @@ -220,11 +306,11 @@ "cannot read counter"); qc->hits_set = 1; qc->bytes_set = 1; - qc->hits = counters[0] - flow->counter->hits; - qc->bytes = counters[1] - flow->counter->bytes; + qc->hits = counters[0] - cnt->hits; + qc->bytes = counters[1] - cnt->bytes; if (qc->reset) { - flow->counter->hits = counters[0]; - flow->counter->bytes = counters[1]; + cnt->hits = counters[0]; + cnt->bytes = counters[1]; } return 0; } @@ -976,6 +1062,7 @@ { const struct rte_flow_action_count *count = action->conf; struct rte_flow *flow = dev_flow->flow; + struct mlx5_flow_counter *cnt = NULL; #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) || \ defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) unsigned int size = sizeof(struct ibv_flow_spec_counter_action); @@ -995,11 +1082,13 @@ "cannot get counter" " context."); } + cnt = flow_verbs_counter_get_by_idx(dev, (uintptr_t)(void *) + flow->counter, NULL); #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) - counter.counter_set_handle = flow->counter->cs->handle; + counter.counter_set_handle = cnt->cs->handle; flow_verbs_spec_add(&dev_flow->verbs, &counter, size); #elif defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45) - counter.counters = flow->counter->cs; + counter.counters = cnt->cs; flow_verbs_spec_add(&dev_flow->verbs, &counter, size); #endif return 0; -- 1.8.3.1