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 1E6C7A2F67 for ; Fri, 4 Oct 2019 21:56:47 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CAED51D15C; Fri, 4 Oct 2019 21:55:59 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 1F7AF1C43D for ; Fri, 4 Oct 2019 21:55:45 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from orika@mellanox.com) with ESMTPS (AES256-SHA encrypted); 4 Oct 2019 22:55:39 +0300 Received: from pegasus04.mtr.labs.mlnx. (pegasus04.mtr.labs.mlnx [10.210.16.126]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x94JsxSp006678; Fri, 4 Oct 2019 22:55:39 +0300 From: Ori Kam To: Matan Azrad , Shahaf Shuler , Viacheslav Ovsiienko Cc: dev@dpdk.org, orika@mellanox.com, jingjing.wu@intel.com, stephen@networkplumber.org Date: Fri, 4 Oct 2019 19:54:12 +0000 Message-Id: <1570218855-73478-12-git-send-email-orika@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1570218855-73478-1-git-send-email-orika@mellanox.com> References: <1569479349-36962-1-git-send-email-orika@mellanox.com> <1570218855-73478-1-git-send-email-orika@mellanox.com> Subject: [dpdk-dev] [PATCH v2 11/14] net/mlx5: add id generation function 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" When splitting flows for example in hairpin / metering, there is a need to combine the flows. This is done using ID. This commit introduce a simple way to generate such IDs. The reason why bitmap was not used is due to fact that the release and allocation are O(n) while in the chosen approch the allocation and release are O(1) Signed-off-by: Ori Kam Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5.c | 120 ++++++++++++++++++++++++++++++++++++++++++- drivers/net/mlx5/mlx5_flow.h | 14 +++++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 55b891a..0b5c19c 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -179,6 +179,124 @@ struct mlx5_dev_spawn_data { static LIST_HEAD(, mlx5_ibv_shared) mlx5_ibv_list = LIST_HEAD_INITIALIZER(); static pthread_mutex_t mlx5_ibv_list_mutex = PTHREAD_MUTEX_INITIALIZER; +#define MLX5_FLOW_MIN_ID_POOL_SIZE 512 +#define MLX5_ID_GENERATION_ARRAY_FACTOR 16 + +/** + * Allocate ID pool structure. + * + * @return + * Pointer to pool object, NULL value otherwise. + */ +struct mlx5_flow_id_pool * +mlx5_flow_id_pool_alloc(void) +{ + struct mlx5_flow_id_pool *pool; + void *mem; + + pool = rte_zmalloc("id pool allocation", sizeof(*pool), + RTE_CACHE_LINE_SIZE); + if (!pool) { + DRV_LOG(ERR, "can't allocate id pool"); + rte_errno = ENOMEM; + return NULL; + } + mem = rte_zmalloc("", MLX5_FLOW_MIN_ID_POOL_SIZE * sizeof(uint32_t), + RTE_CACHE_LINE_SIZE); + if (!mem) { + DRV_LOG(ERR, "can't allocate mem for id pool"); + rte_errno = ENOMEM; + goto error; + } + pool->free_arr = mem; + pool->curr = pool->free_arr; + pool->last = pool->free_arr + MLX5_FLOW_MIN_ID_POOL_SIZE; + pool->base_index = 0; + return pool; +error: + rte_free(pool); + return NULL; +} + +/** + * Release ID pool structure. + * + * @param[in] pool + * Pointer to flow id pool object to free. + */ +void +mlx5_flow_id_pool_release(struct mlx5_flow_id_pool *pool) +{ + rte_free(pool->free_arr); + rte_free(pool); +} + +/** + * Generate ID. + * + * @param[in] pool + * Pointer to flow id pool. + * @param[out] id + * The generated ID. + * + * @return + * 0 on success, error value otherwise. + */ +uint32_t +mlx5_flow_id_get(struct mlx5_flow_id_pool *pool, uint32_t *id) +{ + if (pool->curr == pool->free_arr) { + if (pool->base_index == UINT32_MAX) { + rte_errno = ENOMEM; + DRV_LOG(ERR, "no free id"); + return -rte_errno; + } + *id = ++pool->base_index; + return 0; + } + *id = *(--pool->curr); + return 0; +} + +/** + * Release ID. + * + * @param[in] pool + * Pointer to flow id pool. + * @param[out] id + * The generated ID. + * + * @return + * 0 on success, error value otherwise. + */ +uint32_t +mlx5_flow_id_release(struct mlx5_flow_id_pool *pool, uint32_t id) +{ + uint32_t size; + uint32_t size2; + void *mem; + + if (pool->curr == pool->last) { + size = pool->curr - pool->free_arr; + size2 = size * MLX5_ID_GENERATION_ARRAY_FACTOR; + assert(size2 > size); + mem = rte_malloc("", size2 * sizeof(uint32_t), 0); + if (!mem) { + DRV_LOG(ERR, "can't allocate mem for id pool"); + rte_errno = ENOMEM; + return -rte_errno; + } + memcpy(mem, pool->free_arr, size * sizeof(uint32_t)); + rte_free(pool->free_arr); + pool->free_arr = mem; + pool->curr = pool->free_arr + size; + pool->last = pool->free_arr + size2; + } + *pool->curr = id; + pool->curr++; + return 0; +} + /** * Initialize the counters management structure. * @@ -329,7 +447,7 @@ struct mlx5_dev_spawn_data { struct mlx5_devx_tis_attr tis_attr = { 0 }; #endif - assert(spawn); +assert(spawn); /* Secondary process should not create the shared context. */ assert(rte_eal_process_type() == RTE_PROC_PRIMARY); pthread_mutex_lock(&mlx5_ibv_list_mutex); diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 0148c1b..1b14fb7 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -495,8 +495,22 @@ struct mlx5_flow_driver_ops { #define MLX5_CNT_CONTAINER_UNUSED(sh, batch, thread) (&(sh)->cmng.ccont \ [(~((sh)->cmng.mhi[batch] >> (thread)) & 0x1) * 2 + (batch)]) +/* ID generation structure. */ +struct mlx5_flow_id_pool { + uint32_t *free_arr; /**< Pointer to the a array of free values. */ + uint32_t base_index; + /**< The next index that can be used without any free elements. */ + uint32_t *curr; /**< Pointer to the index to pop. */ + uint32_t *last; /**< Pointer to the last element in the empty arrray. */ +}; + /* mlx5_flow.c */ +struct mlx5_flow_id_pool *mlx5_flow_id_pool_alloc(void); +void mlx5_flow_id_pool_release(struct mlx5_flow_id_pool *pool); +uint32_t mlx5_flow_id_get(struct mlx5_flow_id_pool *pool, uint32_t *id); +uint32_t mlx5_flow_id_release(struct mlx5_flow_id_pool *pool, + uint32_t id); int mlx5_flow_group_to_table(const struct rte_flow_attr *attributes, bool external, uint32_t group, uint32_t *table, struct rte_flow_error *error); -- 1.8.3.1