xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_pool.c (revision 3d4e27fd7ff050d565c7450930c92fb945706518)
1b4dd7bcbSErez Shitrit /* SPDX-License-Identifier: BSD-3-Clause
2b4dd7bcbSErez Shitrit  * Copyright (c) 2022 NVIDIA Corporation & Affiliates
3b4dd7bcbSErez Shitrit  */
4b4dd7bcbSErez Shitrit 
5b4dd7bcbSErez Shitrit #include <rte_bitmap.h>
6b4dd7bcbSErez Shitrit #include <rte_malloc.h>
7b4dd7bcbSErez Shitrit #include "mlx5dr_buddy.h"
8b4dd7bcbSErez Shitrit #include "mlx5dr_internal.h"
9b4dd7bcbSErez Shitrit 
mlx5dr_pool_free_one_resource(struct mlx5dr_pool_resource * resource)10b4dd7bcbSErez Shitrit static void mlx5dr_pool_free_one_resource(struct mlx5dr_pool_resource *resource)
11b4dd7bcbSErez Shitrit {
12b4dd7bcbSErez Shitrit 	mlx5dr_cmd_destroy_obj(resource->devx_obj);
13b4dd7bcbSErez Shitrit 
14b4dd7bcbSErez Shitrit 	simple_free(resource);
15b4dd7bcbSErez Shitrit }
16b4dd7bcbSErez Shitrit 
mlx5dr_pool_resource_free(struct mlx5dr_pool * pool,int resource_idx)17b4dd7bcbSErez Shitrit static void mlx5dr_pool_resource_free(struct mlx5dr_pool *pool,
18b4dd7bcbSErez Shitrit 				      int resource_idx)
19b4dd7bcbSErez Shitrit {
20b4dd7bcbSErez Shitrit 	mlx5dr_pool_free_one_resource(pool->resource[resource_idx]);
21b4dd7bcbSErez Shitrit 	pool->resource[resource_idx] = NULL;
22b4dd7bcbSErez Shitrit 
23b4dd7bcbSErez Shitrit 	if (pool->tbl_type == MLX5DR_TABLE_TYPE_FDB) {
24b4dd7bcbSErez Shitrit 		mlx5dr_pool_free_one_resource(pool->mirror_resource[resource_idx]);
25b4dd7bcbSErez Shitrit 		pool->mirror_resource[resource_idx] = NULL;
26b4dd7bcbSErez Shitrit 	}
27b4dd7bcbSErez Shitrit }
28b4dd7bcbSErez Shitrit 
29b4dd7bcbSErez Shitrit static struct mlx5dr_pool_resource *
mlx5dr_pool_create_one_resource(struct mlx5dr_pool * pool,uint32_t log_range,uint32_t fw_ft_type)30b4dd7bcbSErez Shitrit mlx5dr_pool_create_one_resource(struct mlx5dr_pool *pool, uint32_t log_range,
31b4dd7bcbSErez Shitrit 				uint32_t fw_ft_type)
32b4dd7bcbSErez Shitrit {
33b4dd7bcbSErez Shitrit 	struct mlx5dr_cmd_ste_create_attr ste_attr;
34b4dd7bcbSErez Shitrit 	struct mlx5dr_cmd_stc_create_attr stc_attr;
35b4dd7bcbSErez Shitrit 	struct mlx5dr_pool_resource *resource;
36b4dd7bcbSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
37b4dd7bcbSErez Shitrit 
38b4dd7bcbSErez Shitrit 	resource = simple_malloc(sizeof(*resource));
39b4dd7bcbSErez Shitrit 	if (!resource) {
40b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
41b4dd7bcbSErez Shitrit 		return NULL;
42b4dd7bcbSErez Shitrit 	}
43b4dd7bcbSErez Shitrit 
44b4dd7bcbSErez Shitrit 	switch (pool->type) {
45b4dd7bcbSErez Shitrit 	case MLX5DR_POOL_TYPE_STE:
46b4dd7bcbSErez Shitrit 		ste_attr.log_obj_range = log_range;
47b4dd7bcbSErez Shitrit 		ste_attr.table_type = fw_ft_type;
48b4dd7bcbSErez Shitrit 		devx_obj = mlx5dr_cmd_ste_create(pool->ctx->ibv_ctx, &ste_attr);
49b4dd7bcbSErez Shitrit 		break;
50b4dd7bcbSErez Shitrit 	case MLX5DR_POOL_TYPE_STC:
51b4dd7bcbSErez Shitrit 		stc_attr.log_obj_range = log_range;
52b4dd7bcbSErez Shitrit 		stc_attr.table_type = fw_ft_type;
53b4dd7bcbSErez Shitrit 		devx_obj = mlx5dr_cmd_stc_create(pool->ctx->ibv_ctx, &stc_attr);
54b4dd7bcbSErez Shitrit 		break;
55b4dd7bcbSErez Shitrit 	default:
56b4dd7bcbSErez Shitrit 		assert(0);
57b4dd7bcbSErez Shitrit 		break;
58b4dd7bcbSErez Shitrit 	}
59b4dd7bcbSErez Shitrit 
60b4dd7bcbSErez Shitrit 	if (!devx_obj) {
61b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to allocate resource objects");
62b4dd7bcbSErez Shitrit 		goto free_resource;
63b4dd7bcbSErez Shitrit 	}
64b4dd7bcbSErez Shitrit 
65b4dd7bcbSErez Shitrit 	resource->pool = pool;
66b4dd7bcbSErez Shitrit 	resource->devx_obj = devx_obj;
67b4dd7bcbSErez Shitrit 	resource->range = 1 << log_range;
68b4dd7bcbSErez Shitrit 	resource->base_id = devx_obj->id;
69b4dd7bcbSErez Shitrit 
70b4dd7bcbSErez Shitrit 	return resource;
71b4dd7bcbSErez Shitrit 
72b4dd7bcbSErez Shitrit free_resource:
73b4dd7bcbSErez Shitrit 	simple_free(resource);
74b4dd7bcbSErez Shitrit 	return NULL;
75b4dd7bcbSErez Shitrit }
76b4dd7bcbSErez Shitrit 
77b4dd7bcbSErez Shitrit static int
mlx5dr_pool_resource_alloc(struct mlx5dr_pool * pool,uint32_t log_range,int idx)78b4dd7bcbSErez Shitrit mlx5dr_pool_resource_alloc(struct mlx5dr_pool *pool, uint32_t log_range, int idx)
79b4dd7bcbSErez Shitrit {
80b4dd7bcbSErez Shitrit 	struct mlx5dr_pool_resource *resource;
81b4dd7bcbSErez Shitrit 	uint32_t fw_ft_type, opt_log_range;
82b4dd7bcbSErez Shitrit 
83b4dd7bcbSErez Shitrit 	fw_ft_type = mlx5dr_table_get_res_fw_ft_type(pool->tbl_type, false);
84b4dd7bcbSErez Shitrit 	opt_log_range = pool->opt_type == MLX5DR_POOL_OPTIMIZE_ORIG ? 0 : log_range;
85b4dd7bcbSErez Shitrit 	resource = mlx5dr_pool_create_one_resource(pool, opt_log_range, fw_ft_type);
86b4dd7bcbSErez Shitrit 	if (!resource) {
87b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed allocating resource");
88b4dd7bcbSErez Shitrit 		return rte_errno;
89b4dd7bcbSErez Shitrit 	}
90b4dd7bcbSErez Shitrit 	pool->resource[idx] = resource;
91b4dd7bcbSErez Shitrit 
92b4dd7bcbSErez Shitrit 	if (pool->tbl_type == MLX5DR_TABLE_TYPE_FDB) {
93b4dd7bcbSErez Shitrit 		struct mlx5dr_pool_resource *mir_resource;
94b4dd7bcbSErez Shitrit 
95b4dd7bcbSErez Shitrit 		fw_ft_type = mlx5dr_table_get_res_fw_ft_type(pool->tbl_type, true);
96b4dd7bcbSErez Shitrit 		opt_log_range = pool->opt_type == MLX5DR_POOL_OPTIMIZE_MIRROR ? 0 : log_range;
97b4dd7bcbSErez Shitrit 		mir_resource = mlx5dr_pool_create_one_resource(pool, opt_log_range, fw_ft_type);
98b4dd7bcbSErez Shitrit 		if (!mir_resource) {
99b4dd7bcbSErez Shitrit 			DR_LOG(ERR, "Failed allocating mirrored resource");
100b4dd7bcbSErez Shitrit 			mlx5dr_pool_free_one_resource(resource);
101b4dd7bcbSErez Shitrit 			pool->resource[idx] = NULL;
102b4dd7bcbSErez Shitrit 			return rte_errno;
103b4dd7bcbSErez Shitrit 		}
104b4dd7bcbSErez Shitrit 		pool->mirror_resource[idx] = mir_resource;
105b4dd7bcbSErez Shitrit 	}
106b4dd7bcbSErez Shitrit 
107b4dd7bcbSErez Shitrit 	return 0;
108b4dd7bcbSErez Shitrit }
109b4dd7bcbSErez Shitrit 
mlx5dr_pool_bitmap_get_free_slot(struct rte_bitmap * bitmap,uint32_t * iidx)110b4dd7bcbSErez Shitrit static int mlx5dr_pool_bitmap_get_free_slot(struct rte_bitmap *bitmap, uint32_t *iidx)
111b4dd7bcbSErez Shitrit {
112b4dd7bcbSErez Shitrit 	uint64_t slab = 0;
113b4dd7bcbSErez Shitrit 
114b4dd7bcbSErez Shitrit 	__rte_bitmap_scan_init(bitmap);
115b4dd7bcbSErez Shitrit 
116b4dd7bcbSErez Shitrit 	if (!rte_bitmap_scan(bitmap, iidx, &slab))
117b4dd7bcbSErez Shitrit 		return ENOMEM;
118b4dd7bcbSErez Shitrit 
119*3d4e27fdSDavid Marchand 	*iidx += rte_ctz64(slab);
120b4dd7bcbSErez Shitrit 
121b4dd7bcbSErez Shitrit 	rte_bitmap_clear(bitmap, *iidx);
122b4dd7bcbSErez Shitrit 
123b4dd7bcbSErez Shitrit 	return 0;
124b4dd7bcbSErez Shitrit }
125b4dd7bcbSErez Shitrit 
mlx5dr_pool_create_and_init_bitmap(uint32_t log_range)126b4dd7bcbSErez Shitrit static struct rte_bitmap *mlx5dr_pool_create_and_init_bitmap(uint32_t log_range)
127b4dd7bcbSErez Shitrit {
128b4dd7bcbSErez Shitrit 	struct rte_bitmap *cur_bmp;
129b4dd7bcbSErez Shitrit 	uint32_t bmp_size;
130b4dd7bcbSErez Shitrit 	void *mem;
131b4dd7bcbSErez Shitrit 
132b4dd7bcbSErez Shitrit 	bmp_size = rte_bitmap_get_memory_footprint(1 << log_range);
133b4dd7bcbSErez Shitrit 	mem = rte_zmalloc("create_stc_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
134b4dd7bcbSErez Shitrit 	if (!mem) {
135b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "No mem for bitmap");
136b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
137b4dd7bcbSErez Shitrit 		return NULL;
138b4dd7bcbSErez Shitrit 	}
139b4dd7bcbSErez Shitrit 
140b4dd7bcbSErez Shitrit 	cur_bmp = rte_bitmap_init_with_all_set(1 << log_range, mem, bmp_size);
141b4dd7bcbSErez Shitrit 	if (!cur_bmp) {
142b4dd7bcbSErez Shitrit 		rte_free(mem);
143b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to initialize stc bitmap.");
144b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
145b4dd7bcbSErez Shitrit 		return NULL;
146b4dd7bcbSErez Shitrit 	}
147b4dd7bcbSErez Shitrit 
148b4dd7bcbSErez Shitrit 	return cur_bmp;
149b4dd7bcbSErez Shitrit }
150b4dd7bcbSErez Shitrit 
mlx5dr_pool_buddy_db_put_chunk(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)151b4dd7bcbSErez Shitrit static void mlx5dr_pool_buddy_db_put_chunk(struct mlx5dr_pool *pool,
152b4dd7bcbSErez Shitrit 				      struct mlx5dr_pool_chunk *chunk)
153b4dd7bcbSErez Shitrit {
154b4dd7bcbSErez Shitrit 	struct mlx5dr_buddy_mem *buddy;
155b4dd7bcbSErez Shitrit 
156b4dd7bcbSErez Shitrit 	buddy = pool->db.buddy_manager->buddies[chunk->resource_idx];
157b4dd7bcbSErez Shitrit 	if (!buddy) {
158b4dd7bcbSErez Shitrit 		assert(false);
159b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "No such buddy (%d)", chunk->resource_idx);
160b4dd7bcbSErez Shitrit 		return;
161b4dd7bcbSErez Shitrit 	}
162b4dd7bcbSErez Shitrit 
163b4dd7bcbSErez Shitrit 	mlx5dr_buddy_free_mem(buddy, chunk->offset, chunk->order);
164b4dd7bcbSErez Shitrit }
165b4dd7bcbSErez Shitrit 
166b4dd7bcbSErez Shitrit static struct mlx5dr_buddy_mem *
mlx5dr_pool_buddy_get_next_buddy(struct mlx5dr_pool * pool,int idx,uint32_t order,bool * is_new_buddy)167b4dd7bcbSErez Shitrit mlx5dr_pool_buddy_get_next_buddy(struct mlx5dr_pool *pool, int idx,
168b4dd7bcbSErez Shitrit 				 uint32_t order, bool *is_new_buddy)
169b4dd7bcbSErez Shitrit {
170b4dd7bcbSErez Shitrit 	static struct mlx5dr_buddy_mem *buddy;
171b4dd7bcbSErez Shitrit 	uint32_t new_buddy_size;
172b4dd7bcbSErez Shitrit 
173b4dd7bcbSErez Shitrit 	buddy = pool->db.buddy_manager->buddies[idx];
174b4dd7bcbSErez Shitrit 	if (buddy)
175b4dd7bcbSErez Shitrit 		return buddy;
176b4dd7bcbSErez Shitrit 
177b4dd7bcbSErez Shitrit 	new_buddy_size = RTE_MAX(pool->alloc_log_sz, order);
178b4dd7bcbSErez Shitrit 	*is_new_buddy = true;
179b4dd7bcbSErez Shitrit 	buddy = mlx5dr_buddy_create(new_buddy_size);
180b4dd7bcbSErez Shitrit 	if (!buddy) {
181b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to create buddy order: %d index: %d",
182b4dd7bcbSErez Shitrit 		       new_buddy_size, idx);
183b4dd7bcbSErez Shitrit 		return NULL;
184b4dd7bcbSErez Shitrit 	}
185b4dd7bcbSErez Shitrit 
186b4dd7bcbSErez Shitrit 	if (mlx5dr_pool_resource_alloc(pool, new_buddy_size, idx) != 0) {
187b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to create resource type: %d: size %d index: %d",
188b4dd7bcbSErez Shitrit 			pool->type, new_buddy_size, idx);
189b4dd7bcbSErez Shitrit 		mlx5dr_buddy_cleanup(buddy);
190b4dd7bcbSErez Shitrit 		return NULL;
191b4dd7bcbSErez Shitrit 	}
192b4dd7bcbSErez Shitrit 
193b4dd7bcbSErez Shitrit 	pool->db.buddy_manager->buddies[idx] = buddy;
194b4dd7bcbSErez Shitrit 
195b4dd7bcbSErez Shitrit 	return buddy;
196b4dd7bcbSErez Shitrit }
197b4dd7bcbSErez Shitrit 
mlx5dr_pool_buddy_get_mem_chunk(struct mlx5dr_pool * pool,int order,uint32_t * buddy_idx,int * seg)198b4dd7bcbSErez Shitrit static int mlx5dr_pool_buddy_get_mem_chunk(struct mlx5dr_pool *pool,
199b4dd7bcbSErez Shitrit 					   int order,
200b4dd7bcbSErez Shitrit 					   uint32_t *buddy_idx,
201b4dd7bcbSErez Shitrit 					   int *seg)
202b4dd7bcbSErez Shitrit {
203b4dd7bcbSErez Shitrit 	struct mlx5dr_buddy_mem *buddy;
204b4dd7bcbSErez Shitrit 	bool new_mem = false;
205b4dd7bcbSErez Shitrit 	int err = 0;
206b4dd7bcbSErez Shitrit 	int i;
207b4dd7bcbSErez Shitrit 
208b4dd7bcbSErez Shitrit 	*seg = -1;
209b4dd7bcbSErez Shitrit 
210b4dd7bcbSErez Shitrit 	/* Find the next free place from the buddy array */
211b4dd7bcbSErez Shitrit 	while (*seg == -1) {
212b4dd7bcbSErez Shitrit 		for (i = 0; i < MLX5DR_POOL_RESOURCE_ARR_SZ; i++) {
213b4dd7bcbSErez Shitrit 			buddy = mlx5dr_pool_buddy_get_next_buddy(pool, i,
214b4dd7bcbSErez Shitrit 								 order,
215b4dd7bcbSErez Shitrit 								 &new_mem);
216b4dd7bcbSErez Shitrit 			if (!buddy) {
217b4dd7bcbSErez Shitrit 				err = rte_errno;
218b4dd7bcbSErez Shitrit 				goto out;
219b4dd7bcbSErez Shitrit 			}
220b4dd7bcbSErez Shitrit 
221b4dd7bcbSErez Shitrit 			*seg = mlx5dr_buddy_alloc_mem(buddy, order);
222b4dd7bcbSErez Shitrit 			if (*seg != -1)
223b4dd7bcbSErez Shitrit 				goto found;
224b4dd7bcbSErez Shitrit 
225b4dd7bcbSErez Shitrit 			if (pool->flags & MLX5DR_POOL_FLAGS_ONE_RESOURCE) {
226b4dd7bcbSErez Shitrit 				DR_LOG(ERR, "Fail to allocate seg for one resource pool");
227b4dd7bcbSErez Shitrit 				err = rte_errno;
228b4dd7bcbSErez Shitrit 				goto out;
229b4dd7bcbSErez Shitrit 			}
230b4dd7bcbSErez Shitrit 
231b4dd7bcbSErez Shitrit 			if (new_mem) {
232b4dd7bcbSErez Shitrit 				/* We have new memory pool, should be place for us */
233b4dd7bcbSErez Shitrit 				assert(false);
234b4dd7bcbSErez Shitrit 				DR_LOG(ERR, "No memory for order: %d with buddy no: %d",
235b4dd7bcbSErez Shitrit 					order, i);
236b4dd7bcbSErez Shitrit 				rte_errno = ENOMEM;
237b4dd7bcbSErez Shitrit 				err = ENOMEM;
238b4dd7bcbSErez Shitrit 				goto out;
239b4dd7bcbSErez Shitrit 			}
240b4dd7bcbSErez Shitrit 		}
241b4dd7bcbSErez Shitrit 	}
242b4dd7bcbSErez Shitrit 
243b4dd7bcbSErez Shitrit found:
244b4dd7bcbSErez Shitrit 	*buddy_idx = i;
245b4dd7bcbSErez Shitrit out:
246b4dd7bcbSErez Shitrit 	return err;
247b4dd7bcbSErez Shitrit }
248b4dd7bcbSErez Shitrit 
mlx5dr_pool_buddy_db_get_chunk(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)249b4dd7bcbSErez Shitrit static int mlx5dr_pool_buddy_db_get_chunk(struct mlx5dr_pool *pool,
250b4dd7bcbSErez Shitrit 				     struct mlx5dr_pool_chunk *chunk)
251b4dd7bcbSErez Shitrit {
252b4dd7bcbSErez Shitrit 	int ret = 0;
253b4dd7bcbSErez Shitrit 
254b4dd7bcbSErez Shitrit 	/* Go over the buddies and find next free slot */
255b4dd7bcbSErez Shitrit 	ret = mlx5dr_pool_buddy_get_mem_chunk(pool, chunk->order,
256b4dd7bcbSErez Shitrit 					      &chunk->resource_idx,
257b4dd7bcbSErez Shitrit 					      &chunk->offset);
258b4dd7bcbSErez Shitrit 	if (ret)
259b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to get free slot for chunk with order: %d",
260b4dd7bcbSErez Shitrit 			chunk->order);
261b4dd7bcbSErez Shitrit 
262b4dd7bcbSErez Shitrit 	return ret;
263b4dd7bcbSErez Shitrit }
264b4dd7bcbSErez Shitrit 
mlx5dr_pool_buddy_db_uninit(struct mlx5dr_pool * pool)265b4dd7bcbSErez Shitrit static void mlx5dr_pool_buddy_db_uninit(struct mlx5dr_pool *pool)
266b4dd7bcbSErez Shitrit {
267b4dd7bcbSErez Shitrit 	struct mlx5dr_buddy_mem *buddy;
268b4dd7bcbSErez Shitrit 	int i;
269b4dd7bcbSErez Shitrit 
270b4dd7bcbSErez Shitrit 	for (i = 0; i < MLX5DR_POOL_RESOURCE_ARR_SZ; i++) {
271b4dd7bcbSErez Shitrit 		buddy = pool->db.buddy_manager->buddies[i];
272b4dd7bcbSErez Shitrit 		if (buddy) {
273b4dd7bcbSErez Shitrit 			mlx5dr_buddy_cleanup(buddy);
274b4dd7bcbSErez Shitrit 			simple_free(buddy);
275b4dd7bcbSErez Shitrit 			pool->db.buddy_manager->buddies[i] = NULL;
276b4dd7bcbSErez Shitrit 		}
277b4dd7bcbSErez Shitrit 	}
278b4dd7bcbSErez Shitrit 
279b4dd7bcbSErez Shitrit 	simple_free(pool->db.buddy_manager);
280b4dd7bcbSErez Shitrit }
281b4dd7bcbSErez Shitrit 
mlx5dr_pool_buddy_db_init(struct mlx5dr_pool * pool,uint32_t log_range)282b4dd7bcbSErez Shitrit static int mlx5dr_pool_buddy_db_init(struct mlx5dr_pool *pool, uint32_t log_range)
283b4dd7bcbSErez Shitrit {
284b4dd7bcbSErez Shitrit 	pool->db.buddy_manager = simple_calloc(1, sizeof(*pool->db.buddy_manager));
285b4dd7bcbSErez Shitrit 	if (!pool->db.buddy_manager) {
286b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "No mem for buddy_manager with log_range: %d", log_range);
287b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
288b4dd7bcbSErez Shitrit 		return rte_errno;
289b4dd7bcbSErez Shitrit 	}
290b4dd7bcbSErez Shitrit 
291b4dd7bcbSErez Shitrit 	if (pool->flags & MLX5DR_POOL_FLAGS_ALLOC_MEM_ON_CREATE) {
292b4dd7bcbSErez Shitrit 		bool new_buddy;
293b4dd7bcbSErez Shitrit 
294b4dd7bcbSErez Shitrit 		if (!mlx5dr_pool_buddy_get_next_buddy(pool, 0, log_range, &new_buddy)) {
295b4dd7bcbSErez Shitrit 			DR_LOG(ERR, "Failed allocating memory on create log_sz: %d", log_range);
296b4dd7bcbSErez Shitrit 			simple_free(pool->db.buddy_manager);
297b4dd7bcbSErez Shitrit 			return rte_errno;
298b4dd7bcbSErez Shitrit 		}
299b4dd7bcbSErez Shitrit 	}
300b4dd7bcbSErez Shitrit 
301b4dd7bcbSErez Shitrit 	pool->p_db_uninit = &mlx5dr_pool_buddy_db_uninit;
302b4dd7bcbSErez Shitrit 	pool->p_get_chunk = &mlx5dr_pool_buddy_db_get_chunk;
303b4dd7bcbSErez Shitrit 	pool->p_put_chunk = &mlx5dr_pool_buddy_db_put_chunk;
304b4dd7bcbSErez Shitrit 
305b4dd7bcbSErez Shitrit 	return 0;
306b4dd7bcbSErez Shitrit }
307b4dd7bcbSErez Shitrit 
mlx5dr_pool_create_resource_on_index(struct mlx5dr_pool * pool,uint32_t alloc_size,int idx)308b4dd7bcbSErez Shitrit static int mlx5dr_pool_create_resource_on_index(struct mlx5dr_pool *pool,
309b4dd7bcbSErez Shitrit 						uint32_t alloc_size, int idx)
310b4dd7bcbSErez Shitrit {
311b4dd7bcbSErez Shitrit 	if (mlx5dr_pool_resource_alloc(pool, alloc_size, idx) != 0) {
312b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to create resource type: %d: size %d index: %d",
313b4dd7bcbSErez Shitrit 			pool->type, alloc_size, idx);
314b4dd7bcbSErez Shitrit 		return rte_errno;
315b4dd7bcbSErez Shitrit 	}
316b4dd7bcbSErez Shitrit 
317b4dd7bcbSErez Shitrit 	return 0;
318b4dd7bcbSErez Shitrit }
319b4dd7bcbSErez Shitrit 
320b4dd7bcbSErez Shitrit static struct mlx5dr_pool_elements *
mlx5dr_pool_element_create_new_elem(struct mlx5dr_pool * pool,uint32_t order,int idx)321b4dd7bcbSErez Shitrit mlx5dr_pool_element_create_new_elem(struct mlx5dr_pool *pool, uint32_t order, int idx)
322b4dd7bcbSErez Shitrit {
323b4dd7bcbSErez Shitrit 	struct mlx5dr_pool_elements *elem;
324b4dd7bcbSErez Shitrit 	uint32_t alloc_size;
325b4dd7bcbSErez Shitrit 
326b4dd7bcbSErez Shitrit 	alloc_size = pool->alloc_log_sz;
327b4dd7bcbSErez Shitrit 
328b4dd7bcbSErez Shitrit 	elem = simple_calloc(1, sizeof(*elem));
329b4dd7bcbSErez Shitrit 	if (!elem) {
330b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to create elem order: %d index: %d",
331b4dd7bcbSErez Shitrit 		       order, idx);
332b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
333b4dd7bcbSErez Shitrit 		return NULL;
334b4dd7bcbSErez Shitrit 	}
335b4dd7bcbSErez Shitrit 	/*sharing the same resource, also means that all the elements are with size 1*/
336b4dd7bcbSErez Shitrit 	if ((pool->flags & MLX5DR_POOL_FLAGS_FIXED_SIZE_OBJECTS) &&
337b4dd7bcbSErez Shitrit 	    !(pool->flags & MLX5DR_POOL_FLAGS_RESOURCE_PER_CHUNK)) {
338b4dd7bcbSErez Shitrit 		 /* Currently all chunks in size 1 */
339b4dd7bcbSErez Shitrit 		elem->bitmap =  mlx5dr_pool_create_and_init_bitmap(alloc_size - order);
340b4dd7bcbSErez Shitrit 		if (!elem->bitmap) {
341b4dd7bcbSErez Shitrit 			DR_LOG(ERR, "Failed to create bitmap type: %d: size %d index: %d",
342b4dd7bcbSErez Shitrit 			       pool->type, alloc_size, idx);
343b4dd7bcbSErez Shitrit 			goto free_elem;
344b4dd7bcbSErez Shitrit 		}
345b4dd7bcbSErez Shitrit 	}
346b4dd7bcbSErez Shitrit 
347b4dd7bcbSErez Shitrit 	if (mlx5dr_pool_create_resource_on_index(pool, alloc_size, idx)) {
348b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to create resource type: %d: size %d index: %d",
349b4dd7bcbSErez Shitrit 			pool->type, alloc_size, idx);
350b4dd7bcbSErez Shitrit 		goto free_db;
351b4dd7bcbSErez Shitrit 	}
352b4dd7bcbSErez Shitrit 
353b4dd7bcbSErez Shitrit 	pool->db.element_manager->elements[idx] = elem;
354b4dd7bcbSErez Shitrit 
355b4dd7bcbSErez Shitrit 	return elem;
356b4dd7bcbSErez Shitrit 
357b4dd7bcbSErez Shitrit free_db:
358b4dd7bcbSErez Shitrit 	rte_free(elem->bitmap);
359b4dd7bcbSErez Shitrit free_elem:
360b4dd7bcbSErez Shitrit 	simple_free(elem);
361b4dd7bcbSErez Shitrit 	return NULL;
362b4dd7bcbSErez Shitrit }
363b4dd7bcbSErez Shitrit 
mlx5dr_pool_element_find_seg(struct mlx5dr_pool_elements * elem,int * seg)364b4dd7bcbSErez Shitrit static int mlx5dr_pool_element_find_seg(struct mlx5dr_pool_elements *elem, int *seg)
365b4dd7bcbSErez Shitrit {
366b4dd7bcbSErez Shitrit 	if (mlx5dr_pool_bitmap_get_free_slot(elem->bitmap, (uint32_t *)seg)) {
367b4dd7bcbSErez Shitrit 		elem->is_full = true;
368b4dd7bcbSErez Shitrit 		return ENOMEM;
369b4dd7bcbSErez Shitrit 	}
370b4dd7bcbSErez Shitrit 	return 0;
371b4dd7bcbSErez Shitrit }
372b4dd7bcbSErez Shitrit 
373b4dd7bcbSErez Shitrit static int
mlx5dr_pool_onesize_element_get_mem_chunk(struct mlx5dr_pool * pool,uint32_t order,uint32_t * idx,int * seg)374b4dd7bcbSErez Shitrit mlx5dr_pool_onesize_element_get_mem_chunk(struct mlx5dr_pool *pool, uint32_t order,
375b4dd7bcbSErez Shitrit 					  uint32_t *idx, int *seg)
376b4dd7bcbSErez Shitrit {
377b4dd7bcbSErez Shitrit 	struct mlx5dr_pool_elements *elem;
378b4dd7bcbSErez Shitrit 
379b4dd7bcbSErez Shitrit 	elem = pool->db.element_manager->elements[0];
380b4dd7bcbSErez Shitrit 	if (!elem)
381b4dd7bcbSErez Shitrit 		elem = mlx5dr_pool_element_create_new_elem(pool, order, 0);
382b4dd7bcbSErez Shitrit 	if (!elem)
383b4dd7bcbSErez Shitrit 		goto err_no_elem;
384b4dd7bcbSErez Shitrit 
385b4dd7bcbSErez Shitrit 	*idx = 0;
386b4dd7bcbSErez Shitrit 
387b4dd7bcbSErez Shitrit 	if (mlx5dr_pool_element_find_seg(elem, seg) != 0) {
388b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "No more resources (last request order: %d)", order);
389b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
390b4dd7bcbSErez Shitrit 		return ENOMEM;
391b4dd7bcbSErez Shitrit 	}
392b4dd7bcbSErez Shitrit 
393b4dd7bcbSErez Shitrit 	elem->num_of_elements++;
394b4dd7bcbSErez Shitrit 	return 0;
395b4dd7bcbSErez Shitrit 
396b4dd7bcbSErez Shitrit err_no_elem:
397b4dd7bcbSErez Shitrit 	DR_LOG(ERR, "Failed to allocate element for order: %d", order);
398b4dd7bcbSErez Shitrit 	return ENOMEM;
399b4dd7bcbSErez Shitrit }
400b4dd7bcbSErez Shitrit 
401b4dd7bcbSErez Shitrit static int
mlx5dr_pool_general_element_get_mem_chunk(struct mlx5dr_pool * pool,uint32_t order,uint32_t * idx,int * seg)402b4dd7bcbSErez Shitrit mlx5dr_pool_general_element_get_mem_chunk(struct mlx5dr_pool *pool, uint32_t order,
403b4dd7bcbSErez Shitrit 					  uint32_t *idx, int *seg)
404b4dd7bcbSErez Shitrit {
405b4dd7bcbSErez Shitrit 	int ret;
406b4dd7bcbSErez Shitrit 	int i;
407b4dd7bcbSErez Shitrit 
408b4dd7bcbSErez Shitrit 	for (i = 0; i < MLX5DR_POOL_RESOURCE_ARR_SZ; i++) {
409b4dd7bcbSErez Shitrit 		if (!pool->resource[i]) {
410b4dd7bcbSErez Shitrit 			ret = mlx5dr_pool_create_resource_on_index(pool, order, i);
411b4dd7bcbSErez Shitrit 			if (ret)
412b4dd7bcbSErez Shitrit 				goto err_no_res;
413b4dd7bcbSErez Shitrit 			*idx = i;
414b4dd7bcbSErez Shitrit 			*seg = 0; /* One memory slot in that element */
415b4dd7bcbSErez Shitrit 			return 0;
416b4dd7bcbSErez Shitrit 		}
417b4dd7bcbSErez Shitrit 	}
418b4dd7bcbSErez Shitrit 
419b4dd7bcbSErez Shitrit 	rte_errno = ENOMEM;
420b4dd7bcbSErez Shitrit 	DR_LOG(ERR, "No more resources (last request order: %d)", order);
421b4dd7bcbSErez Shitrit 	return ENOMEM;
422b4dd7bcbSErez Shitrit 
423b4dd7bcbSErez Shitrit err_no_res:
424b4dd7bcbSErez Shitrit 	DR_LOG(ERR, "Failed to allocate element for order: %d", order);
425b4dd7bcbSErez Shitrit 	return ENOMEM;
426b4dd7bcbSErez Shitrit }
427b4dd7bcbSErez Shitrit 
mlx5dr_pool_general_element_db_get_chunk(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)428b4dd7bcbSErez Shitrit static int mlx5dr_pool_general_element_db_get_chunk(struct mlx5dr_pool *pool,
429b4dd7bcbSErez Shitrit 						    struct mlx5dr_pool_chunk *chunk)
430b4dd7bcbSErez Shitrit {
431b4dd7bcbSErez Shitrit 	int ret;
432b4dd7bcbSErez Shitrit 
433b4dd7bcbSErez Shitrit 	/* Go over all memory elements and find/allocate free slot */
434b4dd7bcbSErez Shitrit 	ret = mlx5dr_pool_general_element_get_mem_chunk(pool, chunk->order,
435b4dd7bcbSErez Shitrit 							&chunk->resource_idx,
436b4dd7bcbSErez Shitrit 							&chunk->offset);
437b4dd7bcbSErez Shitrit 	if (ret)
438b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to get free slot for chunk with order: %d",
439b4dd7bcbSErez Shitrit 			chunk->order);
440b4dd7bcbSErez Shitrit 
441b4dd7bcbSErez Shitrit 	return ret;
442b4dd7bcbSErez Shitrit }
443b4dd7bcbSErez Shitrit 
mlx5dr_pool_general_element_db_put_chunk(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)444b4dd7bcbSErez Shitrit static void mlx5dr_pool_general_element_db_put_chunk(struct mlx5dr_pool *pool,
445b4dd7bcbSErez Shitrit 						     struct mlx5dr_pool_chunk *chunk)
446b4dd7bcbSErez Shitrit {
447b4dd7bcbSErez Shitrit 	assert(pool->resource[chunk->resource_idx]);
448b4dd7bcbSErez Shitrit 
449b4dd7bcbSErez Shitrit 	if (pool->flags & MLX5DR_POOL_FLAGS_RELEASE_FREE_RESOURCE)
450b4dd7bcbSErez Shitrit 		mlx5dr_pool_resource_free(pool, chunk->resource_idx);
451b4dd7bcbSErez Shitrit }
452b4dd7bcbSErez Shitrit 
mlx5dr_pool_general_element_db_uninit(struct mlx5dr_pool * pool)453b4dd7bcbSErez Shitrit static void mlx5dr_pool_general_element_db_uninit(struct mlx5dr_pool *pool)
454b4dd7bcbSErez Shitrit {
455b4dd7bcbSErez Shitrit 	(void)pool;
456b4dd7bcbSErez Shitrit }
457b4dd7bcbSErez Shitrit 
458b4dd7bcbSErez Shitrit /* This memory management works as the following:
459b4dd7bcbSErez Shitrit  * - At start doesn't allocate no mem at all.
460b4dd7bcbSErez Shitrit  * - When new request for chunk arrived:
461b4dd7bcbSErez Shitrit  *	allocate resource and give it.
462b4dd7bcbSErez Shitrit  * - When free that chunk:
463b4dd7bcbSErez Shitrit  *	the resource is freed.
464b4dd7bcbSErez Shitrit  */
mlx5dr_pool_general_element_db_init(struct mlx5dr_pool * pool)465b4dd7bcbSErez Shitrit static int mlx5dr_pool_general_element_db_init(struct mlx5dr_pool *pool)
466b4dd7bcbSErez Shitrit {
467b4dd7bcbSErez Shitrit 	pool->p_db_uninit = &mlx5dr_pool_general_element_db_uninit;
468b4dd7bcbSErez Shitrit 	pool->p_get_chunk = &mlx5dr_pool_general_element_db_get_chunk;
469b4dd7bcbSErez Shitrit 	pool->p_put_chunk = &mlx5dr_pool_general_element_db_put_chunk;
470b4dd7bcbSErez Shitrit 
471b4dd7bcbSErez Shitrit 	return 0;
472b4dd7bcbSErez Shitrit }
473b4dd7bcbSErez Shitrit 
mlx5dr_onesize_element_db_destroy_element(struct mlx5dr_pool * pool,struct mlx5dr_pool_elements * elem,struct mlx5dr_pool_chunk * chunk)474b4dd7bcbSErez Shitrit static void mlx5dr_onesize_element_db_destroy_element(struct mlx5dr_pool *pool,
475b4dd7bcbSErez Shitrit 						      struct mlx5dr_pool_elements *elem,
476b4dd7bcbSErez Shitrit 						      struct mlx5dr_pool_chunk *chunk)
477b4dd7bcbSErez Shitrit {
478b4dd7bcbSErez Shitrit 	assert(pool->resource[chunk->resource_idx]);
479b4dd7bcbSErez Shitrit 
480b4dd7bcbSErez Shitrit 	mlx5dr_pool_resource_free(pool, chunk->resource_idx);
481b4dd7bcbSErez Shitrit 
482b4dd7bcbSErez Shitrit 	simple_free(elem);
483b4dd7bcbSErez Shitrit 	pool->db.element_manager->elements[chunk->resource_idx] = NULL;
484b4dd7bcbSErez Shitrit }
485b4dd7bcbSErez Shitrit 
mlx5dr_onesize_element_db_put_chunk(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)486b4dd7bcbSErez Shitrit static void mlx5dr_onesize_element_db_put_chunk(struct mlx5dr_pool *pool,
487b4dd7bcbSErez Shitrit 						struct mlx5dr_pool_chunk *chunk)
488b4dd7bcbSErez Shitrit {
489b4dd7bcbSErez Shitrit 	struct mlx5dr_pool_elements *elem;
490b4dd7bcbSErez Shitrit 
491b4dd7bcbSErez Shitrit 	assert(chunk->resource_idx == 0);
492b4dd7bcbSErez Shitrit 
493b4dd7bcbSErez Shitrit 	elem = pool->db.element_manager->elements[chunk->resource_idx];
494b4dd7bcbSErez Shitrit 	if (!elem) {
495b4dd7bcbSErez Shitrit 		assert(false);
496b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "No such element (%d)", chunk->resource_idx);
497b4dd7bcbSErez Shitrit 		return;
498b4dd7bcbSErez Shitrit 	}
499b4dd7bcbSErez Shitrit 
500b4dd7bcbSErez Shitrit 	rte_bitmap_set(elem->bitmap, chunk->offset);
501b4dd7bcbSErez Shitrit 	elem->is_full = false;
502b4dd7bcbSErez Shitrit 	elem->num_of_elements--;
503b4dd7bcbSErez Shitrit 
504b4dd7bcbSErez Shitrit 	if (pool->flags & MLX5DR_POOL_FLAGS_RELEASE_FREE_RESOURCE &&
505b4dd7bcbSErez Shitrit 	   !elem->num_of_elements)
506b4dd7bcbSErez Shitrit 		mlx5dr_onesize_element_db_destroy_element(pool, elem, chunk);
507b4dd7bcbSErez Shitrit }
508b4dd7bcbSErez Shitrit 
mlx5dr_onesize_element_db_get_chunk(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)509b4dd7bcbSErez Shitrit static int mlx5dr_onesize_element_db_get_chunk(struct mlx5dr_pool *pool,
510b4dd7bcbSErez Shitrit 					       struct mlx5dr_pool_chunk *chunk)
511b4dd7bcbSErez Shitrit {
512b4dd7bcbSErez Shitrit 	int ret = 0;
513b4dd7bcbSErez Shitrit 
514b4dd7bcbSErez Shitrit 	/* Go over all memory elements and find/allocate free slot */
515b4dd7bcbSErez Shitrit 	ret = mlx5dr_pool_onesize_element_get_mem_chunk(pool, chunk->order,
516b4dd7bcbSErez Shitrit 							&chunk->resource_idx,
517b4dd7bcbSErez Shitrit 							&chunk->offset);
518b4dd7bcbSErez Shitrit 	if (ret)
519b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to get free slot for chunk with order: %d",
520b4dd7bcbSErez Shitrit 			chunk->order);
521b4dd7bcbSErez Shitrit 
522b4dd7bcbSErez Shitrit 	return ret;
523b4dd7bcbSErez Shitrit }
524b4dd7bcbSErez Shitrit 
mlx5dr_onesize_element_db_uninit(struct mlx5dr_pool * pool)525b4dd7bcbSErez Shitrit static void mlx5dr_onesize_element_db_uninit(struct mlx5dr_pool *pool)
526b4dd7bcbSErez Shitrit {
527b4dd7bcbSErez Shitrit 	struct mlx5dr_pool_elements *elem;
528b4dd7bcbSErez Shitrit 	int i;
529b4dd7bcbSErez Shitrit 
530b4dd7bcbSErez Shitrit 	for (i = 0; i < MLX5DR_POOL_RESOURCE_ARR_SZ; i++) {
531b4dd7bcbSErez Shitrit 		elem = pool->db.element_manager->elements[i];
532b4dd7bcbSErez Shitrit 		if (elem) {
533b4dd7bcbSErez Shitrit 			rte_free(elem->bitmap);
534b4dd7bcbSErez Shitrit 			simple_free(elem);
535b4dd7bcbSErez Shitrit 			pool->db.element_manager->elements[i] = NULL;
536b4dd7bcbSErez Shitrit 		}
537b4dd7bcbSErez Shitrit 	}
538b4dd7bcbSErez Shitrit 	simple_free(pool->db.element_manager);
539b4dd7bcbSErez Shitrit }
540b4dd7bcbSErez Shitrit 
541b4dd7bcbSErez Shitrit /* This memory management works as the following:
542b4dd7bcbSErez Shitrit  * - At start doesn't allocate no mem at all.
543b4dd7bcbSErez Shitrit  * - When new request for chunk arrived:
544b4dd7bcbSErez Shitrit  *  aloocate the first and only slot of memory/resource
545b4dd7bcbSErez Shitrit  *  when it ended return error.
546b4dd7bcbSErez Shitrit  */
mlx5dr_pool_onesize_element_db_init(struct mlx5dr_pool * pool)547b4dd7bcbSErez Shitrit static int mlx5dr_pool_onesize_element_db_init(struct mlx5dr_pool *pool)
548b4dd7bcbSErez Shitrit {
549b4dd7bcbSErez Shitrit 	pool->db.element_manager = simple_calloc(1, sizeof(*pool->db.element_manager));
550b4dd7bcbSErez Shitrit 	if (!pool->db.element_manager) {
551b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "No mem for general elemnt_manager");
552b4dd7bcbSErez Shitrit 		rte_errno = ENOMEM;
553b4dd7bcbSErez Shitrit 		return rte_errno;
554b4dd7bcbSErez Shitrit 	}
555b4dd7bcbSErez Shitrit 
556b4dd7bcbSErez Shitrit 	pool->p_db_uninit = &mlx5dr_onesize_element_db_uninit;
557b4dd7bcbSErez Shitrit 	pool->p_get_chunk = &mlx5dr_onesize_element_db_get_chunk;
558b4dd7bcbSErez Shitrit 	pool->p_put_chunk = &mlx5dr_onesize_element_db_put_chunk;
559b4dd7bcbSErez Shitrit 
560b4dd7bcbSErez Shitrit 	return 0;
561b4dd7bcbSErez Shitrit }
562b4dd7bcbSErez Shitrit 
mlx5dr_pool_db_init(struct mlx5dr_pool * pool,enum mlx5dr_db_type db_type)563b4dd7bcbSErez Shitrit static int mlx5dr_pool_db_init(struct mlx5dr_pool *pool,
564b4dd7bcbSErez Shitrit 			       enum mlx5dr_db_type db_type)
565b4dd7bcbSErez Shitrit {
566b4dd7bcbSErez Shitrit 	int ret;
567b4dd7bcbSErez Shitrit 
568b4dd7bcbSErez Shitrit 	if (db_type == MLX5DR_POOL_DB_TYPE_GENERAL_SIZE)
569b4dd7bcbSErez Shitrit 		ret = mlx5dr_pool_general_element_db_init(pool);
570b4dd7bcbSErez Shitrit 	else if (db_type == MLX5DR_POOL_DB_TYPE_ONE_SIZE_RESOURCE)
571b4dd7bcbSErez Shitrit 		ret = mlx5dr_pool_onesize_element_db_init(pool);
572b4dd7bcbSErez Shitrit 	else
573b4dd7bcbSErez Shitrit 		ret = mlx5dr_pool_buddy_db_init(pool, pool->alloc_log_sz);
574b4dd7bcbSErez Shitrit 
575b4dd7bcbSErez Shitrit 	if (ret) {
576b4dd7bcbSErez Shitrit 		DR_LOG(ERR, "Failed to init general db : %d (ret: %d)", db_type, ret);
577b4dd7bcbSErez Shitrit 		return ret;
578b4dd7bcbSErez Shitrit 	}
579b4dd7bcbSErez Shitrit 
580b4dd7bcbSErez Shitrit 	return 0;
581b4dd7bcbSErez Shitrit }
582b4dd7bcbSErez Shitrit 
mlx5dr_pool_db_unint(struct mlx5dr_pool * pool)583b4dd7bcbSErez Shitrit static void mlx5dr_pool_db_unint(struct mlx5dr_pool *pool)
584b4dd7bcbSErez Shitrit {
585b4dd7bcbSErez Shitrit 	pool->p_db_uninit(pool);
586b4dd7bcbSErez Shitrit }
587b4dd7bcbSErez Shitrit 
588b4dd7bcbSErez Shitrit int
mlx5dr_pool_chunk_alloc(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)589b4dd7bcbSErez Shitrit mlx5dr_pool_chunk_alloc(struct mlx5dr_pool *pool,
590b4dd7bcbSErez Shitrit 			struct mlx5dr_pool_chunk *chunk)
591b4dd7bcbSErez Shitrit {
592b4dd7bcbSErez Shitrit 	int ret;
593b4dd7bcbSErez Shitrit 
594b4dd7bcbSErez Shitrit 	pthread_spin_lock(&pool->lock);
595b4dd7bcbSErez Shitrit 	ret = pool->p_get_chunk(pool, chunk);
596b4dd7bcbSErez Shitrit 	pthread_spin_unlock(&pool->lock);
597b4dd7bcbSErez Shitrit 
598b4dd7bcbSErez Shitrit 	return ret;
599b4dd7bcbSErez Shitrit }
600b4dd7bcbSErez Shitrit 
mlx5dr_pool_chunk_free(struct mlx5dr_pool * pool,struct mlx5dr_pool_chunk * chunk)601b4dd7bcbSErez Shitrit void mlx5dr_pool_chunk_free(struct mlx5dr_pool *pool,
602b4dd7bcbSErez Shitrit 			    struct mlx5dr_pool_chunk *chunk)
603b4dd7bcbSErez Shitrit {
604b4dd7bcbSErez Shitrit 	pthread_spin_lock(&pool->lock);
605b4dd7bcbSErez Shitrit 	pool->p_put_chunk(pool, chunk);
606b4dd7bcbSErez Shitrit 	pthread_spin_unlock(&pool->lock);
607b4dd7bcbSErez Shitrit }
608b4dd7bcbSErez Shitrit 
609b4dd7bcbSErez Shitrit struct mlx5dr_pool *
mlx5dr_pool_create(struct mlx5dr_context * ctx,struct mlx5dr_pool_attr * pool_attr)610b4dd7bcbSErez Shitrit mlx5dr_pool_create(struct mlx5dr_context *ctx, struct mlx5dr_pool_attr *pool_attr)
611b4dd7bcbSErez Shitrit {
612b4dd7bcbSErez Shitrit 	enum mlx5dr_db_type res_db_type;
613b4dd7bcbSErez Shitrit 	struct mlx5dr_pool *pool;
614b4dd7bcbSErez Shitrit 
615b4dd7bcbSErez Shitrit 	pool = simple_calloc(1, sizeof(*pool));
616b4dd7bcbSErez Shitrit 	if (!pool)
617b4dd7bcbSErez Shitrit 		return NULL;
618b4dd7bcbSErez Shitrit 
619b4dd7bcbSErez Shitrit 	pool->ctx = ctx;
620b4dd7bcbSErez Shitrit 	pool->type = pool_attr->pool_type;
621b4dd7bcbSErez Shitrit 	pool->alloc_log_sz = pool_attr->alloc_log_sz;
622b4dd7bcbSErez Shitrit 	pool->flags = pool_attr->flags;
623b4dd7bcbSErez Shitrit 	pool->tbl_type = pool_attr->table_type;
624b4dd7bcbSErez Shitrit 	pool->opt_type = pool_attr->opt_type;
625b4dd7bcbSErez Shitrit 
626b4dd7bcbSErez Shitrit 	pthread_spin_init(&pool->lock, PTHREAD_PROCESS_PRIVATE);
627b4dd7bcbSErez Shitrit 
628b4dd7bcbSErez Shitrit 	/* Support general db */
629b4dd7bcbSErez Shitrit 	if (pool->flags == (MLX5DR_POOL_FLAGS_RELEASE_FREE_RESOURCE |
630b4dd7bcbSErez Shitrit 			    MLX5DR_POOL_FLAGS_RESOURCE_PER_CHUNK))
631b4dd7bcbSErez Shitrit 		res_db_type = MLX5DR_POOL_DB_TYPE_GENERAL_SIZE;
632b4dd7bcbSErez Shitrit 	else if (pool->flags == (MLX5DR_POOL_FLAGS_ONE_RESOURCE |
633b4dd7bcbSErez Shitrit 				 MLX5DR_POOL_FLAGS_FIXED_SIZE_OBJECTS))
634b4dd7bcbSErez Shitrit 		res_db_type = MLX5DR_POOL_DB_TYPE_ONE_SIZE_RESOURCE;
635b4dd7bcbSErez Shitrit 	else
636b4dd7bcbSErez Shitrit 		res_db_type = MLX5DR_POOL_DB_TYPE_BUDDY;
637b4dd7bcbSErez Shitrit 
638b4dd7bcbSErez Shitrit 	pool->alloc_log_sz = pool_attr->alloc_log_sz;
639b4dd7bcbSErez Shitrit 
640b4dd7bcbSErez Shitrit 	if (mlx5dr_pool_db_init(pool, res_db_type))
641b4dd7bcbSErez Shitrit 		goto free_pool;
642b4dd7bcbSErez Shitrit 
643b4dd7bcbSErez Shitrit 	return pool;
644b4dd7bcbSErez Shitrit 
645b4dd7bcbSErez Shitrit free_pool:
646b4dd7bcbSErez Shitrit 	pthread_spin_destroy(&pool->lock);
647b4dd7bcbSErez Shitrit 	simple_free(pool);
648b4dd7bcbSErez Shitrit 	return NULL;
649b4dd7bcbSErez Shitrit }
650b4dd7bcbSErez Shitrit 
mlx5dr_pool_destroy(struct mlx5dr_pool * pool)651b4dd7bcbSErez Shitrit int mlx5dr_pool_destroy(struct mlx5dr_pool *pool)
652b4dd7bcbSErez Shitrit {
653b4dd7bcbSErez Shitrit 	int i;
654b4dd7bcbSErez Shitrit 
655b4dd7bcbSErez Shitrit 	for (i = 0; i < MLX5DR_POOL_RESOURCE_ARR_SZ; i++)
656b4dd7bcbSErez Shitrit 		if (pool->resource[i])
657b4dd7bcbSErez Shitrit 			mlx5dr_pool_resource_free(pool, i);
658b4dd7bcbSErez Shitrit 
659b4dd7bcbSErez Shitrit 	mlx5dr_pool_db_unint(pool);
660b4dd7bcbSErez Shitrit 
661b4dd7bcbSErez Shitrit 	pthread_spin_destroy(&pool->lock);
662b4dd7bcbSErez Shitrit 	simple_free(pool);
663b4dd7bcbSErez Shitrit 	return 0;
664b4dd7bcbSErez Shitrit }
665