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