1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2024 NVIDIA Corporation & Affiliates */
3
4 #include "mlx5hws_internal.h"
5 #include "mlx5hws_buddy.h"
6
hws_pool_free_one_resource(struct mlx5hws_pool_resource * resource)7 static void hws_pool_free_one_resource(struct mlx5hws_pool_resource *resource)
8 {
9 switch (resource->pool->type) {
10 case MLX5HWS_POOL_TYPE_STE:
11 mlx5hws_cmd_ste_destroy(resource->pool->ctx->mdev, resource->base_id);
12 break;
13 case MLX5HWS_POOL_TYPE_STC:
14 mlx5hws_cmd_stc_destroy(resource->pool->ctx->mdev, resource->base_id);
15 break;
16 default:
17 break;
18 }
19
20 kfree(resource);
21 }
22
hws_pool_resource_free(struct mlx5hws_pool * pool,int resource_idx)23 static void hws_pool_resource_free(struct mlx5hws_pool *pool,
24 int resource_idx)
25 {
26 hws_pool_free_one_resource(pool->resource[resource_idx]);
27 pool->resource[resource_idx] = NULL;
28
29 if (pool->tbl_type == MLX5HWS_TABLE_TYPE_FDB) {
30 hws_pool_free_one_resource(pool->mirror_resource[resource_idx]);
31 pool->mirror_resource[resource_idx] = NULL;
32 }
33 }
34
35 static struct mlx5hws_pool_resource *
hws_pool_create_one_resource(struct mlx5hws_pool * pool,u32 log_range,u32 fw_ft_type)36 hws_pool_create_one_resource(struct mlx5hws_pool *pool, u32 log_range,
37 u32 fw_ft_type)
38 {
39 struct mlx5hws_cmd_ste_create_attr ste_attr;
40 struct mlx5hws_cmd_stc_create_attr stc_attr;
41 struct mlx5hws_pool_resource *resource;
42 u32 obj_id = 0;
43 int ret;
44
45 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
46 if (!resource)
47 return NULL;
48
49 switch (pool->type) {
50 case MLX5HWS_POOL_TYPE_STE:
51 ste_attr.log_obj_range = log_range;
52 ste_attr.table_type = fw_ft_type;
53 ret = mlx5hws_cmd_ste_create(pool->ctx->mdev, &ste_attr, &obj_id);
54 break;
55 case MLX5HWS_POOL_TYPE_STC:
56 stc_attr.log_obj_range = log_range;
57 stc_attr.table_type = fw_ft_type;
58 ret = mlx5hws_cmd_stc_create(pool->ctx->mdev, &stc_attr, &obj_id);
59 break;
60 default:
61 ret = -EINVAL;
62 }
63
64 if (ret) {
65 mlx5hws_err(pool->ctx, "Failed to allocate resource objects\n");
66 goto free_resource;
67 }
68
69 resource->pool = pool;
70 resource->range = 1 << log_range;
71 resource->base_id = obj_id;
72
73 return resource;
74
75 free_resource:
76 kfree(resource);
77 return NULL;
78 }
79
80 static int
hws_pool_resource_alloc(struct mlx5hws_pool * pool,u32 log_range,int idx)81 hws_pool_resource_alloc(struct mlx5hws_pool *pool, u32 log_range, int idx)
82 {
83 struct mlx5hws_pool_resource *resource;
84 u32 fw_ft_type, opt_log_range;
85
86 fw_ft_type = mlx5hws_table_get_res_fw_ft_type(pool->tbl_type, false);
87 opt_log_range = pool->opt_type == MLX5HWS_POOL_OPTIMIZE_ORIG ? 0 : log_range;
88 resource = hws_pool_create_one_resource(pool, opt_log_range, fw_ft_type);
89 if (!resource) {
90 mlx5hws_err(pool->ctx, "Failed allocating resource\n");
91 return -EINVAL;
92 }
93
94 pool->resource[idx] = resource;
95
96 if (pool->tbl_type == MLX5HWS_TABLE_TYPE_FDB) {
97 struct mlx5hws_pool_resource *mirror_resource;
98
99 fw_ft_type = mlx5hws_table_get_res_fw_ft_type(pool->tbl_type, true);
100 opt_log_range = pool->opt_type == MLX5HWS_POOL_OPTIMIZE_MIRROR ? 0 : log_range;
101 mirror_resource = hws_pool_create_one_resource(pool, opt_log_range, fw_ft_type);
102 if (!mirror_resource) {
103 mlx5hws_err(pool->ctx, "Failed allocating mirrored resource\n");
104 hws_pool_free_one_resource(resource);
105 pool->resource[idx] = NULL;
106 return -EINVAL;
107 }
108 pool->mirror_resource[idx] = mirror_resource;
109 }
110
111 return 0;
112 }
113
hws_pool_create_and_init_bitmap(u32 log_range)114 static unsigned long *hws_pool_create_and_init_bitmap(u32 log_range)
115 {
116 unsigned long *cur_bmp;
117
118 cur_bmp = bitmap_zalloc(1 << log_range, GFP_KERNEL);
119 if (!cur_bmp)
120 return NULL;
121
122 bitmap_fill(cur_bmp, 1 << log_range);
123
124 return cur_bmp;
125 }
126
hws_pool_buddy_db_put_chunk(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)127 static void hws_pool_buddy_db_put_chunk(struct mlx5hws_pool *pool,
128 struct mlx5hws_pool_chunk *chunk)
129 {
130 struct mlx5hws_buddy_mem *buddy;
131
132 buddy = pool->db.buddy_manager->buddies[chunk->resource_idx];
133 if (!buddy) {
134 mlx5hws_err(pool->ctx, "No such buddy (%d)\n", chunk->resource_idx);
135 return;
136 }
137
138 mlx5hws_buddy_free_mem(buddy, chunk->offset, chunk->order);
139 }
140
141 static struct mlx5hws_buddy_mem *
hws_pool_buddy_get_next_buddy(struct mlx5hws_pool * pool,int idx,u32 order,bool * is_new_buddy)142 hws_pool_buddy_get_next_buddy(struct mlx5hws_pool *pool, int idx,
143 u32 order, bool *is_new_buddy)
144 {
145 static struct mlx5hws_buddy_mem *buddy;
146 u32 new_buddy_size;
147
148 buddy = pool->db.buddy_manager->buddies[idx];
149 if (buddy)
150 return buddy;
151
152 new_buddy_size = max(pool->alloc_log_sz, order);
153 *is_new_buddy = true;
154 buddy = mlx5hws_buddy_create(new_buddy_size);
155 if (!buddy) {
156 mlx5hws_err(pool->ctx, "Failed to create buddy order: %d index: %d\n",
157 new_buddy_size, idx);
158 return NULL;
159 }
160
161 if (hws_pool_resource_alloc(pool, new_buddy_size, idx) != 0) {
162 mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %d index: %d\n",
163 pool->type, new_buddy_size, idx);
164 mlx5hws_buddy_cleanup(buddy);
165 return NULL;
166 }
167
168 pool->db.buddy_manager->buddies[idx] = buddy;
169
170 return buddy;
171 }
172
hws_pool_buddy_get_mem_chunk(struct mlx5hws_pool * pool,int order,u32 * buddy_idx,int * seg)173 static int hws_pool_buddy_get_mem_chunk(struct mlx5hws_pool *pool,
174 int order,
175 u32 *buddy_idx,
176 int *seg)
177 {
178 struct mlx5hws_buddy_mem *buddy;
179 bool new_mem = false;
180 int ret = 0;
181 int i;
182
183 *seg = -1;
184
185 /* Find the next free place from the buddy array */
186 while (*seg == -1) {
187 for (i = 0; i < MLX5HWS_POOL_RESOURCE_ARR_SZ; i++) {
188 buddy = hws_pool_buddy_get_next_buddy(pool, i,
189 order,
190 &new_mem);
191 if (!buddy) {
192 ret = -ENOMEM;
193 goto out;
194 }
195
196 *seg = mlx5hws_buddy_alloc_mem(buddy, order);
197 if (*seg != -1)
198 goto found;
199
200 if (pool->flags & MLX5HWS_POOL_FLAGS_ONE_RESOURCE) {
201 mlx5hws_err(pool->ctx,
202 "Fail to allocate seg for one resource pool\n");
203 ret = -ENOMEM;
204 goto out;
205 }
206
207 if (new_mem) {
208 /* We have new memory pool, should be place for us */
209 mlx5hws_err(pool->ctx,
210 "No memory for order: %d with buddy no: %d\n",
211 order, i);
212 ret = -ENOMEM;
213 goto out;
214 }
215 }
216 }
217
218 found:
219 *buddy_idx = i;
220 out:
221 return ret;
222 }
223
hws_pool_buddy_db_get_chunk(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)224 static int hws_pool_buddy_db_get_chunk(struct mlx5hws_pool *pool,
225 struct mlx5hws_pool_chunk *chunk)
226 {
227 int ret = 0;
228
229 /* Go over the buddies and find next free slot */
230 ret = hws_pool_buddy_get_mem_chunk(pool, chunk->order,
231 &chunk->resource_idx,
232 &chunk->offset);
233 if (ret)
234 mlx5hws_err(pool->ctx, "Failed to get free slot for chunk with order: %d\n",
235 chunk->order);
236
237 return ret;
238 }
239
hws_pool_buddy_db_uninit(struct mlx5hws_pool * pool)240 static void hws_pool_buddy_db_uninit(struct mlx5hws_pool *pool)
241 {
242 struct mlx5hws_buddy_mem *buddy;
243 int i;
244
245 for (i = 0; i < MLX5HWS_POOL_RESOURCE_ARR_SZ; i++) {
246 buddy = pool->db.buddy_manager->buddies[i];
247 if (buddy) {
248 mlx5hws_buddy_cleanup(buddy);
249 kfree(buddy);
250 pool->db.buddy_manager->buddies[i] = NULL;
251 }
252 }
253
254 kfree(pool->db.buddy_manager);
255 }
256
hws_pool_buddy_db_init(struct mlx5hws_pool * pool,u32 log_range)257 static int hws_pool_buddy_db_init(struct mlx5hws_pool *pool, u32 log_range)
258 {
259 pool->db.buddy_manager = kzalloc(sizeof(*pool->db.buddy_manager), GFP_KERNEL);
260 if (!pool->db.buddy_manager)
261 return -ENOMEM;
262
263 if (pool->flags & MLX5HWS_POOL_FLAGS_ALLOC_MEM_ON_CREATE) {
264 bool new_buddy;
265
266 if (!hws_pool_buddy_get_next_buddy(pool, 0, log_range, &new_buddy)) {
267 mlx5hws_err(pool->ctx,
268 "Failed allocating memory on create log_sz: %d\n", log_range);
269 kfree(pool->db.buddy_manager);
270 return -ENOMEM;
271 }
272 }
273
274 pool->p_db_uninit = &hws_pool_buddy_db_uninit;
275 pool->p_get_chunk = &hws_pool_buddy_db_get_chunk;
276 pool->p_put_chunk = &hws_pool_buddy_db_put_chunk;
277
278 return 0;
279 }
280
hws_pool_create_resource_on_index(struct mlx5hws_pool * pool,u32 alloc_size,int idx)281 static int hws_pool_create_resource_on_index(struct mlx5hws_pool *pool,
282 u32 alloc_size, int idx)
283 {
284 int ret = hws_pool_resource_alloc(pool, alloc_size, idx);
285
286 if (ret) {
287 mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %d index: %d\n",
288 pool->type, alloc_size, idx);
289 return ret;
290 }
291
292 return 0;
293 }
294
295 static struct mlx5hws_pool_elements *
hws_pool_element_create_new_elem(struct mlx5hws_pool * pool,u32 order,int idx)296 hws_pool_element_create_new_elem(struct mlx5hws_pool *pool, u32 order, int idx)
297 {
298 struct mlx5hws_pool_elements *elem;
299 u32 alloc_size;
300
301 alloc_size = pool->alloc_log_sz;
302
303 elem = kzalloc(sizeof(*elem), GFP_KERNEL);
304 if (!elem)
305 return NULL;
306
307 /* Sharing the same resource, also means that all the elements are with size 1 */
308 if ((pool->flags & MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS) &&
309 !(pool->flags & MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK)) {
310 /* Currently all chunks in size 1 */
311 elem->bitmap = hws_pool_create_and_init_bitmap(alloc_size - order);
312 if (!elem->bitmap) {
313 mlx5hws_err(pool->ctx,
314 "Failed to create bitmap type: %d: size %d index: %d\n",
315 pool->type, alloc_size, idx);
316 goto free_elem;
317 }
318
319 elem->log_size = alloc_size - order;
320 }
321
322 if (hws_pool_create_resource_on_index(pool, alloc_size, idx)) {
323 mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %d index: %d\n",
324 pool->type, alloc_size, idx);
325 goto free_db;
326 }
327
328 pool->db.element_manager->elements[idx] = elem;
329
330 return elem;
331
332 free_db:
333 bitmap_free(elem->bitmap);
334 free_elem:
335 kfree(elem);
336 return NULL;
337 }
338
hws_pool_element_find_seg(struct mlx5hws_pool_elements * elem,int * seg)339 static int hws_pool_element_find_seg(struct mlx5hws_pool_elements *elem, int *seg)
340 {
341 unsigned int segment, size;
342
343 size = 1 << elem->log_size;
344
345 segment = find_first_bit(elem->bitmap, size);
346 if (segment >= size) {
347 elem->is_full = true;
348 return -ENOMEM;
349 }
350
351 bitmap_clear(elem->bitmap, segment, 1);
352 *seg = segment;
353 return 0;
354 }
355
356 static int
hws_pool_onesize_element_get_mem_chunk(struct mlx5hws_pool * pool,u32 order,u32 * idx,int * seg)357 hws_pool_onesize_element_get_mem_chunk(struct mlx5hws_pool *pool, u32 order,
358 u32 *idx, int *seg)
359 {
360 struct mlx5hws_pool_elements *elem;
361
362 elem = pool->db.element_manager->elements[0];
363 if (!elem)
364 elem = hws_pool_element_create_new_elem(pool, order, 0);
365 if (!elem)
366 goto err_no_elem;
367
368 if (hws_pool_element_find_seg(elem, seg) != 0) {
369 mlx5hws_err(pool->ctx, "No more resources (last request order: %d)\n", order);
370 return -ENOMEM;
371 }
372
373 *idx = 0;
374 elem->num_of_elements++;
375 return 0;
376
377 err_no_elem:
378 mlx5hws_err(pool->ctx, "Failed to allocate element for order: %d\n", order);
379 return -ENOMEM;
380 }
381
382 static int
hws_pool_general_element_get_mem_chunk(struct mlx5hws_pool * pool,u32 order,u32 * idx,int * seg)383 hws_pool_general_element_get_mem_chunk(struct mlx5hws_pool *pool, u32 order,
384 u32 *idx, int *seg)
385 {
386 int ret, i;
387
388 for (i = 0; i < MLX5HWS_POOL_RESOURCE_ARR_SZ; i++) {
389 if (!pool->resource[i]) {
390 ret = hws_pool_create_resource_on_index(pool, order, i);
391 if (ret)
392 goto err_no_res;
393 *idx = i;
394 *seg = 0; /* One memory slot in that element */
395 return 0;
396 }
397 }
398
399 mlx5hws_err(pool->ctx, "No more resources (last request order: %d)\n", order);
400 return -ENOMEM;
401
402 err_no_res:
403 mlx5hws_err(pool->ctx, "Failed to allocate element for order: %d\n", order);
404 return -ENOMEM;
405 }
406
hws_pool_general_element_db_get_chunk(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)407 static int hws_pool_general_element_db_get_chunk(struct mlx5hws_pool *pool,
408 struct mlx5hws_pool_chunk *chunk)
409 {
410 int ret;
411
412 /* Go over all memory elements and find/allocate free slot */
413 ret = hws_pool_general_element_get_mem_chunk(pool, chunk->order,
414 &chunk->resource_idx,
415 &chunk->offset);
416 if (ret)
417 mlx5hws_err(pool->ctx, "Failed to get free slot for chunk with order: %d\n",
418 chunk->order);
419
420 return ret;
421 }
422
hws_pool_general_element_db_put_chunk(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)423 static void hws_pool_general_element_db_put_chunk(struct mlx5hws_pool *pool,
424 struct mlx5hws_pool_chunk *chunk)
425 {
426 if (unlikely(!pool->resource[chunk->resource_idx]))
427 pr_warn("HWS: invalid resource with index %d\n", chunk->resource_idx);
428
429 if (pool->flags & MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE)
430 hws_pool_resource_free(pool, chunk->resource_idx);
431 }
432
hws_pool_general_element_db_uninit(struct mlx5hws_pool * pool)433 static void hws_pool_general_element_db_uninit(struct mlx5hws_pool *pool)
434 {
435 (void)pool;
436 }
437
438 /* This memory management works as the following:
439 * - At start doesn't allocate no mem at all.
440 * - When new request for chunk arrived:
441 * allocate resource and give it.
442 * - When free that chunk:
443 * the resource is freed.
444 */
hws_pool_general_element_db_init(struct mlx5hws_pool * pool)445 static int hws_pool_general_element_db_init(struct mlx5hws_pool *pool)
446 {
447 pool->p_db_uninit = &hws_pool_general_element_db_uninit;
448 pool->p_get_chunk = &hws_pool_general_element_db_get_chunk;
449 pool->p_put_chunk = &hws_pool_general_element_db_put_chunk;
450
451 return 0;
452 }
453
hws_onesize_element_db_destroy_element(struct mlx5hws_pool * pool,struct mlx5hws_pool_elements * elem,struct mlx5hws_pool_chunk * chunk)454 static void hws_onesize_element_db_destroy_element(struct mlx5hws_pool *pool,
455 struct mlx5hws_pool_elements *elem,
456 struct mlx5hws_pool_chunk *chunk)
457 {
458 if (unlikely(!pool->resource[chunk->resource_idx]))
459 pr_warn("HWS: invalid resource with index %d\n", chunk->resource_idx);
460
461 hws_pool_resource_free(pool, chunk->resource_idx);
462 kfree(elem);
463 pool->db.element_manager->elements[chunk->resource_idx] = NULL;
464 }
465
hws_onesize_element_db_put_chunk(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)466 static void hws_onesize_element_db_put_chunk(struct mlx5hws_pool *pool,
467 struct mlx5hws_pool_chunk *chunk)
468 {
469 struct mlx5hws_pool_elements *elem;
470
471 if (unlikely(chunk->resource_idx))
472 pr_warn("HWS: invalid resource with index %d\n", chunk->resource_idx);
473
474 elem = pool->db.element_manager->elements[chunk->resource_idx];
475 if (!elem) {
476 mlx5hws_err(pool->ctx, "No such element (%d)\n", chunk->resource_idx);
477 return;
478 }
479
480 bitmap_set(elem->bitmap, chunk->offset, 1);
481 elem->is_full = false;
482 elem->num_of_elements--;
483
484 if (pool->flags & MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE &&
485 !elem->num_of_elements)
486 hws_onesize_element_db_destroy_element(pool, elem, chunk);
487 }
488
hws_onesize_element_db_get_chunk(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)489 static int hws_onesize_element_db_get_chunk(struct mlx5hws_pool *pool,
490 struct mlx5hws_pool_chunk *chunk)
491 {
492 int ret = 0;
493
494 /* Go over all memory elements and find/allocate free slot */
495 ret = hws_pool_onesize_element_get_mem_chunk(pool, chunk->order,
496 &chunk->resource_idx,
497 &chunk->offset);
498 if (ret)
499 mlx5hws_err(pool->ctx, "Failed to get free slot for chunk with order: %d\n",
500 chunk->order);
501
502 return ret;
503 }
504
hws_onesize_element_db_uninit(struct mlx5hws_pool * pool)505 static void hws_onesize_element_db_uninit(struct mlx5hws_pool *pool)
506 {
507 struct mlx5hws_pool_elements *elem;
508 int i;
509
510 for (i = 0; i < MLX5HWS_POOL_RESOURCE_ARR_SZ; i++) {
511 elem = pool->db.element_manager->elements[i];
512 if (elem) {
513 bitmap_free(elem->bitmap);
514 kfree(elem);
515 pool->db.element_manager->elements[i] = NULL;
516 }
517 }
518 kfree(pool->db.element_manager);
519 }
520
521 /* This memory management works as the following:
522 * - At start doesn't allocate no mem at all.
523 * - When new request for chunk arrived:
524 * aloocate the first and only slot of memory/resource
525 * when it ended return error.
526 */
hws_pool_onesize_element_db_init(struct mlx5hws_pool * pool)527 static int hws_pool_onesize_element_db_init(struct mlx5hws_pool *pool)
528 {
529 pool->db.element_manager = kzalloc(sizeof(*pool->db.element_manager), GFP_KERNEL);
530 if (!pool->db.element_manager)
531 return -ENOMEM;
532
533 pool->p_db_uninit = &hws_onesize_element_db_uninit;
534 pool->p_get_chunk = &hws_onesize_element_db_get_chunk;
535 pool->p_put_chunk = &hws_onesize_element_db_put_chunk;
536
537 return 0;
538 }
539
hws_pool_db_init(struct mlx5hws_pool * pool,enum mlx5hws_db_type db_type)540 static int hws_pool_db_init(struct mlx5hws_pool *pool,
541 enum mlx5hws_db_type db_type)
542 {
543 int ret;
544
545 if (db_type == MLX5HWS_POOL_DB_TYPE_GENERAL_SIZE)
546 ret = hws_pool_general_element_db_init(pool);
547 else if (db_type == MLX5HWS_POOL_DB_TYPE_ONE_SIZE_RESOURCE)
548 ret = hws_pool_onesize_element_db_init(pool);
549 else
550 ret = hws_pool_buddy_db_init(pool, pool->alloc_log_sz);
551
552 if (ret) {
553 mlx5hws_err(pool->ctx, "Failed to init general db : %d (ret: %d)\n", db_type, ret);
554 return ret;
555 }
556
557 return 0;
558 }
559
hws_pool_db_unint(struct mlx5hws_pool * pool)560 static void hws_pool_db_unint(struct mlx5hws_pool *pool)
561 {
562 pool->p_db_uninit(pool);
563 }
564
mlx5hws_pool_chunk_alloc(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)565 int mlx5hws_pool_chunk_alloc(struct mlx5hws_pool *pool,
566 struct mlx5hws_pool_chunk *chunk)
567 {
568 int ret;
569
570 mutex_lock(&pool->lock);
571 ret = pool->p_get_chunk(pool, chunk);
572 mutex_unlock(&pool->lock);
573
574 return ret;
575 }
576
mlx5hws_pool_chunk_free(struct mlx5hws_pool * pool,struct mlx5hws_pool_chunk * chunk)577 void mlx5hws_pool_chunk_free(struct mlx5hws_pool *pool,
578 struct mlx5hws_pool_chunk *chunk)
579 {
580 mutex_lock(&pool->lock);
581 pool->p_put_chunk(pool, chunk);
582 mutex_unlock(&pool->lock);
583 }
584
585 struct mlx5hws_pool *
mlx5hws_pool_create(struct mlx5hws_context * ctx,struct mlx5hws_pool_attr * pool_attr)586 mlx5hws_pool_create(struct mlx5hws_context *ctx, struct mlx5hws_pool_attr *pool_attr)
587 {
588 enum mlx5hws_db_type res_db_type;
589 struct mlx5hws_pool *pool;
590
591 pool = kzalloc(sizeof(*pool), GFP_KERNEL);
592 if (!pool)
593 return NULL;
594
595 pool->ctx = ctx;
596 pool->type = pool_attr->pool_type;
597 pool->alloc_log_sz = pool_attr->alloc_log_sz;
598 pool->flags = pool_attr->flags;
599 pool->tbl_type = pool_attr->table_type;
600 pool->opt_type = pool_attr->opt_type;
601
602 /* Support general db */
603 if (pool->flags == (MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE |
604 MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK))
605 res_db_type = MLX5HWS_POOL_DB_TYPE_GENERAL_SIZE;
606 else if (pool->flags == (MLX5HWS_POOL_FLAGS_ONE_RESOURCE |
607 MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS))
608 res_db_type = MLX5HWS_POOL_DB_TYPE_ONE_SIZE_RESOURCE;
609 else
610 res_db_type = MLX5HWS_POOL_DB_TYPE_BUDDY;
611
612 pool->alloc_log_sz = pool_attr->alloc_log_sz;
613
614 if (hws_pool_db_init(pool, res_db_type))
615 goto free_pool;
616
617 mutex_init(&pool->lock);
618
619 return pool;
620
621 free_pool:
622 kfree(pool);
623 return NULL;
624 }
625
mlx5hws_pool_destroy(struct mlx5hws_pool * pool)626 int mlx5hws_pool_destroy(struct mlx5hws_pool *pool)
627 {
628 int i;
629
630 mutex_destroy(&pool->lock);
631
632 for (i = 0; i < MLX5HWS_POOL_RESOURCE_ARR_SZ; i++)
633 if (pool->resource[i])
634 hws_pool_resource_free(pool, i);
635
636 hws_pool_db_unint(pool);
637
638 kfree(pool);
639 return 0;
640 }
641