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