| 511 | } |
| 512 | |
| 513 | void * |
| 514 | mlx5_ipool_malloc(struct mlx5_indexed_pool *pool, uint32_t *idx) |
| 515 | { |
| 516 | struct mlx5_indexed_trunk *trunk; |
| 517 | uint64_t slab = 0; |
| 518 | uint32_t iidx = 0; |
| 519 | void *p; |
| 520 | |
| 521 | if (pool->cfg.per_core_cache) |
| 522 | return mlx5_ipool_malloc_cache(pool, idx); |
| 523 | mlx5_ipool_lock(pool); |
| 524 | if (pool->free_list == TRUNK_INVALID) { |
| 525 | /* If no available trunks, grow new. */ |
| 526 | if (mlx5_ipool_grow(pool)) { |
| 527 | mlx5_ipool_unlock(pool); |
| 528 | return NULL; |
| 529 | } |
| 530 | } |
| 531 | MLX5_ASSERT(pool->free_list != TRUNK_INVALID); |
| 532 | trunk = pool->trunks[pool->free_list]; |
| 533 | MLX5_ASSERT(trunk->free); |
| 534 | if (!rte_bitmap_scan(trunk->bmp, &iidx, &slab)) { |
| 535 | mlx5_ipool_unlock(pool); |
| 536 | return NULL; |
| 537 | } |
| 538 | MLX5_ASSERT(slab); |
| 539 | iidx += rte_ctz64(slab); |
| 540 | MLX5_ASSERT(iidx != UINT32_MAX); |
| 541 | MLX5_ASSERT(iidx < mlx5_trunk_size_get(pool, trunk->idx)); |
| 542 | rte_bitmap_clear(trunk->bmp, iidx); |
| 543 | p = &trunk->data[iidx * pool->cfg.size]; |
| 544 | /* |
| 545 | * The ipool index should grow continually from small to big, |
| 546 | * some features as metering only accept limited bits of index. |
| 547 | * Random index with MSB set may be rejected. |
| 548 | */ |
| 549 | iidx += mlx5_trunk_idx_offset_get(pool, trunk->idx); |
| 550 | iidx += 1; /* non-zero index. */ |
| 551 | trunk->free--; |
| 552 | #ifdef POOL_DEBUG |
| 553 | pool->n_entry++; |
| 554 | #endif |
| 555 | if (!trunk->free) { |
| 556 | /* Full trunk will be removed from free list in imalloc. */ |
| 557 | MLX5_ASSERT(pool->free_list == trunk->idx); |
| 558 | pool->free_list = trunk->next; |
| 559 | if (trunk->next != TRUNK_INVALID) |
| 560 | pool->trunks[trunk->next]->prev = TRUNK_INVALID; |
| 561 | trunk->prev = TRUNK_INVALID; |
| 562 | trunk->next = TRUNK_INVALID; |
| 563 | #ifdef POOL_DEBUG |
| 564 | pool->trunk_empty++; |
| 565 | pool->trunk_avail--; |
| 566 | #endif |
| 567 | } |
| 568 | *idx = iidx; |
| 569 | mlx5_ipool_unlock(pool); |
| 570 | return p; |
no test coverage detected