From 1fd4bb67eb2d0c8a62d642e6ec3b78c0452313e8 Mon Sep 17 00:00:00 2001 From: Suanming Mou Date: Thu, 16 Apr 2020 10:42:01 +0800 Subject: [PATCH] net/mlx5: add trunk release for indexed pool While entries are fully freed in trunk, it means the trunk is free now. User may prefer the free trunk memory can be reclaimed. Add the trunk release memory option for indexed pool in this case. Signed-off-by: Suanming Mou Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_utils.c | 37 +++++++++++++++++++++++++++++++---- drivers/net/mlx5/mlx5_utils.h | 1 + 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/net/mlx5/mlx5_utils.c b/drivers/net/mlx5/mlx5_utils.c index ee1939b909..2146ffdc04 100644 --- a/drivers/net/mlx5/mlx5_utils.c +++ b/drivers/net/mlx5/mlx5_utils.c @@ -254,7 +254,14 @@ mlx5_ipool_grow(struct mlx5_indexed_pool *pool) pool->cfg.free(trunk_tmp); pool->n_trunk += n_grow; } - idx = pool->n_trunk_valid; + if (!pool->cfg.release_mem_en) { + idx = pool->n_trunk_valid; + } else { + /* Find the first available slot in trunk list */ + for (idx = 0; idx < pool->n_trunk; idx++) + if (pool->trunks[idx] == NULL) + break; + } trunk_size += sizeof(*trunk); data_size = mlx5_trunk_size_get(pool, idx); bmp_size = rte_bitmap_get_memory_footprint(data_size); @@ -356,7 +363,8 @@ mlx5_ipool_free(struct mlx5_indexed_pool *pool, uint32_t idx) idx -= 1; mlx5_ipool_lock(pool); trunk_idx = mlx5_trunk_idx_get(pool, idx); - if (trunk_idx >= pool->n_trunk_valid) + if ((!pool->cfg.release_mem_en && trunk_idx >= pool->n_trunk_valid) || + (pool->cfg.release_mem_en && trunk_idx >= pool->n_trunk)) goto out; trunk = pool->trunks[trunk_idx]; if (!trunk) @@ -367,7 +375,27 @@ mlx5_ipool_free(struct mlx5_indexed_pool *pool, uint32_t idx) goto out; rte_bitmap_set(trunk->bmp, entry_idx); trunk->free++; - if (trunk->free == 1) { + if (pool->cfg.release_mem_en && trunk->free == mlx5_trunk_size_get + (pool, trunk->idx)) { + if (pool->free_list == trunk->idx) + pool->free_list = trunk->next; + if (trunk->next != TRUNK_INVALID) + pool->trunks[trunk->next]->prev = trunk->prev; + if (trunk->prev != TRUNK_INVALID) + pool->trunks[trunk->prev]->next = trunk->next; + pool->cfg.free(trunk); + pool->trunks[trunk_idx] = NULL; + pool->n_trunk_valid--; +#ifdef POOL_DEBUG + pool->trunk_avail--; + pool->trunk_free++; +#endif + if (pool->n_trunk_valid == 0) { + pool->cfg.free(pool->trunks); + pool->trunks = NULL; + pool->n_trunk = 0; + } + } else if (trunk->free == 1) { /* Put into free trunk list head. */ MLX5_ASSERT(pool->free_list != trunk->idx); trunk->next = pool->free_list; @@ -400,7 +428,8 @@ mlx5_ipool_get(struct mlx5_indexed_pool *pool, uint32_t idx) idx -= 1; mlx5_ipool_lock(pool); trunk_idx = mlx5_trunk_idx_get(pool, idx); - if (trunk_idx >= pool->n_trunk_valid) + if ((!pool->cfg.release_mem_en && trunk_idx >= pool->n_trunk_valid) || + (pool->cfg.release_mem_en && trunk_idx >= pool->n_trunk)) goto out; trunk = pool->trunks[trunk_idx]; if (!trunk) diff --git a/drivers/net/mlx5/mlx5_utils.h b/drivers/net/mlx5/mlx5_utils.h index 53a79d763d..d81ace394e 100644 --- a/drivers/net/mlx5/mlx5_utils.h +++ b/drivers/net/mlx5/mlx5_utils.h @@ -101,6 +101,7 @@ struct mlx5_indexed_pool_config { */ uint32_t need_lock:1; /* Lock is needed for multiple thread usage. */ + uint32_t release_mem_en:1; /* Rlease trunk when it is free. */ const char *type; /* Memory allocate type name. */ void *(*malloc)(const char *type, size_t size, unsigned int align, int socket); -- 2.20.1