Commit d171ce3d authored by Vlad Dogaru's avatar Vlad Dogaru Committed by Jakub Kicinski
Browse files

net/mlx5: HWS, Refactor pool implementation



Refactor the pool implementation to remove unused flags and clarify its
usage. A pool represents a single range of STEs or STCs which are
allocated at pool creation time.

Pools are used under three patterns:

1. STCs are allocated one at a time from a global pool using a bitmap
   based implementation.

2. Action STEs are allocated in power-of-two blocks using a buddy
   algorithm.

3. Match STEs do not use allocation, since insertion into these tables
   is based on hashes or direct addressing. In such cases we use a pool
   only to create the STE range.

Signed-off-by: default avatarVlad Dogaru <vdogaru@nvidia.com>
Reviewed-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: default avatarMark Bloch <mbloch@nvidia.com>
Signed-off-by: default avatarTariq Toukan <tariqt@nvidia.com>
Reviewed-by: default avatarMichal Kubiak <michal.kubiak@intel.com>
Link: https://patch.msgid.link/1744312662-356571-5-git-send-email-tariqt@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 38956bea
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -1602,7 +1602,6 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,

	pool_attr.table_type = MLX5HWS_TABLE_TYPE_FDB;
	pool_attr.pool_type = MLX5HWS_POOL_TYPE_STE;
	pool_attr.flags = MLX5HWS_POOL_FLAGS_FOR_STE_ACTION_POOL;
	pool_attr.alloc_log_sz = 1;
	table_ste->pool = mlx5hws_pool_create(ctx, &pool_attr);
	if (!table_ste->pool) {
+0 −1
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ static int hws_context_pools_init(struct mlx5hws_context *ctx)

	/* Create an STC pool per FT type */
	pool_attr.pool_type = MLX5HWS_POOL_TYPE_STC;
	pool_attr.flags = MLX5HWS_POOL_FLAGS_FOR_STC_POOL;
	max_log_sz = min(MLX5HWS_POOL_STC_LOG_SZ, ctx->caps->stc_alloc_log_max);
	pool_attr.alloc_log_sz = max(max_log_sz, ctx->caps->stc_alloc_log_gran);

+1 −18
Original line number Diff line number Diff line
@@ -265,14 +265,6 @@ static int hws_matcher_create_rtc(struct mlx5hws_matcher *matcher,
				rtc_attr.match_definer_0 = ctx->caps->linear_match_definer;
			}
		}

		/* Match pool requires implicit allocation */
		ret = mlx5hws_pool_chunk_alloc(ste_pool, ste);
		if (ret) {
			mlx5hws_err(ctx, "Failed to allocate STE for %s RTC",
				    hws_matcher_rtc_type_to_str(rtc_type));
			return ret;
		}
		break;

	case HWS_MATCHER_RTC_TYPE_STE_ARRAY:
@@ -357,23 +349,17 @@ static void hws_matcher_destroy_rtc(struct mlx5hws_matcher *matcher,
{
	struct mlx5hws_matcher_action_ste *action_ste;
	struct mlx5hws_table *tbl = matcher->tbl;
	struct mlx5hws_pool_chunk *ste;
	struct mlx5hws_pool *ste_pool;
	u32 rtc_0_id, rtc_1_id;

	switch (rtc_type) {
	case HWS_MATCHER_RTC_TYPE_MATCH:
		rtc_0_id = matcher->match_ste.rtc_0_id;
		rtc_1_id = matcher->match_ste.rtc_1_id;
		ste_pool = matcher->match_ste.pool;
		ste = &matcher->match_ste.ste;
		break;
	case HWS_MATCHER_RTC_TYPE_STE_ARRAY:
		action_ste = &matcher->action_ste;
		rtc_0_id = action_ste->rtc_0_id;
		rtc_1_id = action_ste->rtc_1_id;
		ste_pool = action_ste->pool;
		ste = &action_ste->ste;
		break;
	default:
		return;
@@ -383,8 +369,6 @@ static void hws_matcher_destroy_rtc(struct mlx5hws_matcher *matcher,
		mlx5hws_cmd_rtc_destroy(matcher->tbl->ctx->mdev, rtc_1_id);

	mlx5hws_cmd_rtc_destroy(matcher->tbl->ctx->mdev, rtc_0_id);
	if (rtc_type == HWS_MATCHER_RTC_TYPE_MATCH)
		mlx5hws_pool_chunk_free(ste_pool, ste);
}

static int
@@ -557,7 +541,7 @@ static int hws_matcher_bind_at(struct mlx5hws_matcher *matcher)
	/* Allocate action STE mempool */
	pool_attr.table_type = tbl->type;
	pool_attr.pool_type = MLX5HWS_POOL_TYPE_STE;
	pool_attr.flags = MLX5HWS_POOL_FLAGS_FOR_STE_ACTION_POOL;
	pool_attr.flags = MLX5HWS_POOL_FLAG_BUDDY;
	/* Pool size is similar to action RTC size */
	pool_attr.alloc_log_sz = ilog2(roundup_pow_of_two(action_ste->max_stes)) +
				 matcher->attr.table.sz_row_log +
@@ -636,7 +620,6 @@ static int hws_matcher_bind_mt(struct mlx5hws_matcher *matcher)
	/* Create an STE pool per matcher*/
	pool_attr.table_type = matcher->tbl->type;
	pool_attr.pool_type = MLX5HWS_POOL_TYPE_STE;
	pool_attr.flags = MLX5HWS_POOL_FLAGS_FOR_MATCHER_STE_POOL;
	pool_attr.alloc_log_sz = matcher->attr.table.sz_col_log +
				 matcher->attr.table.sz_row_log;
	hws_matcher_set_pool_attr(&pool_attr, matcher);
+107 −280
Original line number Diff line number Diff line
@@ -60,10 +60,8 @@ hws_pool_create_one_resource(struct mlx5hws_pool *pool, u32 log_range,
		ret = -EINVAL;
	}

	if (ret) {
		mlx5hws_err(pool->ctx, "Failed to allocate resource objects\n");
	if (ret)
		goto free_resource;
	}

	resource->pool = pool;
	resource->range = 1 << log_range;
@@ -76,17 +74,17 @@ hws_pool_create_one_resource(struct mlx5hws_pool *pool, u32 log_range,
	return NULL;
}

static int
hws_pool_resource_alloc(struct mlx5hws_pool *pool, u32 log_range)
static int hws_pool_resource_alloc(struct mlx5hws_pool *pool)
{
	struct mlx5hws_pool_resource *resource;
	u32 fw_ft_type, opt_log_range;

	fw_ft_type = mlx5hws_table_get_res_fw_ft_type(pool->tbl_type, false);
	opt_log_range = pool->opt_type == MLX5HWS_POOL_OPTIMIZE_ORIG ? 0 : log_range;
	opt_log_range = pool->opt_type == MLX5HWS_POOL_OPTIMIZE_ORIG ?
				0 : pool->alloc_log_sz;
	resource = hws_pool_create_one_resource(pool, opt_log_range, fw_ft_type);
	if (!resource) {
		mlx5hws_err(pool->ctx, "Failed allocating resource\n");
		mlx5hws_err(pool->ctx, "Failed to allocate resource\n");
		return -EINVAL;
	}

@@ -96,10 +94,11 @@ hws_pool_resource_alloc(struct mlx5hws_pool *pool, u32 log_range)
		struct mlx5hws_pool_resource *mirror_resource;

		fw_ft_type = mlx5hws_table_get_res_fw_ft_type(pool->tbl_type, true);
		opt_log_range = pool->opt_type == MLX5HWS_POOL_OPTIMIZE_MIRROR ? 0 : log_range;
		opt_log_range = pool->opt_type == MLX5HWS_POOL_OPTIMIZE_MIRROR ?
					0 : pool->alloc_log_sz;
		mirror_resource = hws_pool_create_one_resource(pool, opt_log_range, fw_ft_type);
		if (!mirror_resource) {
			mlx5hws_err(pool->ctx, "Failed allocating mirrored resource\n");
			mlx5hws_err(pool->ctx, "Failed to allocate mirrored resource\n");
			hws_pool_free_one_resource(resource);
			pool->resource = NULL;
			return -EINVAL;
@@ -110,92 +109,58 @@ hws_pool_resource_alloc(struct mlx5hws_pool *pool, u32 log_range)
	return 0;
}

static unsigned long *hws_pool_create_and_init_bitmap(u32 log_range)
{
	unsigned long *cur_bmp;

	cur_bmp = bitmap_zalloc(1 << log_range, GFP_KERNEL);
	if (!cur_bmp)
		return NULL;

	bitmap_fill(cur_bmp, 1 << log_range);

	return cur_bmp;
}

static void hws_pool_buddy_db_put_chunk(struct mlx5hws_pool *pool,
					struct mlx5hws_pool_chunk *chunk)
static int hws_pool_buddy_init(struct mlx5hws_pool *pool)
{
	struct mlx5hws_buddy_mem *buddy;

	buddy = pool->db.buddy;
	buddy = mlx5hws_buddy_create(pool->alloc_log_sz);
	if (!buddy) {
		mlx5hws_err(pool->ctx, "Bad buddy state\n");
		return;
	}

	mlx5hws_buddy_free_mem(buddy, chunk->offset, chunk->order);
}

static struct mlx5hws_buddy_mem *
hws_pool_buddy_get_buddy(struct mlx5hws_pool *pool, u32 order)
{
	static struct mlx5hws_buddy_mem *buddy;
	u32 new_buddy_size;

	buddy = pool->db.buddy;
	if (buddy)
		return buddy;

	new_buddy_size = max(pool->alloc_log_sz, order);
	buddy = mlx5hws_buddy_create(new_buddy_size);
	if (!buddy) {
		mlx5hws_err(pool->ctx, "Failed to create buddy order: %d\n",
			    new_buddy_size);
		return NULL;
		mlx5hws_err(pool->ctx, "Failed to create buddy order: %zu\n",
			    pool->alloc_log_sz);
		return -ENOMEM;
	}

	if (hws_pool_resource_alloc(pool, new_buddy_size) != 0) {
		mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %d\n",
			    pool->type, new_buddy_size);
	if (hws_pool_resource_alloc(pool) != 0) {
		mlx5hws_err(pool->ctx, "Failed to create resource type: %d size %zu\n",
			    pool->type, pool->alloc_log_sz);
		mlx5hws_buddy_cleanup(buddy);
		return NULL;
		return -ENOMEM;
	}

	pool->db.buddy = buddy;

	return buddy;
	return 0;
}

static int hws_pool_buddy_get_mem_chunk(struct mlx5hws_pool *pool,
					int order,
					int *seg)
static int hws_pool_buddy_db_get_chunk(struct mlx5hws_pool *pool,
				       struct mlx5hws_pool_chunk *chunk)
{
	struct mlx5hws_buddy_mem *buddy;
	struct mlx5hws_buddy_mem *buddy = pool->db.buddy;

	buddy = hws_pool_buddy_get_buddy(pool, order);
	if (!buddy)
		return -ENOMEM;
	if (!buddy) {
		mlx5hws_err(pool->ctx, "Bad buddy state\n");
		return -EINVAL;
	}

	*seg = mlx5hws_buddy_alloc_mem(buddy, order);
	if (*seg >= 0)
	chunk->offset = mlx5hws_buddy_alloc_mem(buddy, chunk->order);
	if (chunk->offset >= 0)
		return 0;

	return -ENOMEM;
}

static int hws_pool_buddy_db_get_chunk(struct mlx5hws_pool *pool,
static void hws_pool_buddy_db_put_chunk(struct mlx5hws_pool *pool,
					struct mlx5hws_pool_chunk *chunk)
{
	int ret = 0;
	struct mlx5hws_buddy_mem *buddy;

	ret = hws_pool_buddy_get_mem_chunk(pool, chunk->order,
					   &chunk->offset);
	if (ret)
		mlx5hws_err(pool->ctx, "Failed to get free slot for chunk with order: %d\n",
			    chunk->order);
	buddy = pool->db.buddy;
	if (!buddy) {
		mlx5hws_err(pool->ctx, "Bad buddy state\n");
		return;
	}

	return ret;
	mlx5hws_buddy_free_mem(buddy, chunk->offset, chunk->order);
}

static void hws_pool_buddy_db_uninit(struct mlx5hws_pool *pool)
@@ -210,15 +175,13 @@ static void hws_pool_buddy_db_uninit(struct mlx5hws_pool *pool)
	}
}

static int hws_pool_buddy_db_init(struct mlx5hws_pool *pool, u32 log_range)
static int hws_pool_buddy_db_init(struct mlx5hws_pool *pool)
{
	if (pool->flags & MLX5HWS_POOL_FLAGS_ALLOC_MEM_ON_CREATE) {
		if (!hws_pool_buddy_get_buddy(pool, log_range)) {
			mlx5hws_err(pool->ctx,
				    "Failed allocating memory on create log_sz: %d\n", log_range);
			return -ENOMEM;
		}
	}
	int ret;

	ret = hws_pool_buddy_init(pool);
	if (ret)
		return ret;

	pool->p_db_uninit = &hws_pool_buddy_db_uninit;
	pool->p_get_chunk = &hws_pool_buddy_db_get_chunk;
@@ -227,234 +190,105 @@ static int hws_pool_buddy_db_init(struct mlx5hws_pool *pool, u32 log_range)
	return 0;
}

static int hws_pool_create_resource(struct mlx5hws_pool *pool, u32 alloc_size)
{
	int ret = hws_pool_resource_alloc(pool, alloc_size);

	if (ret) {
		mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %d\n",
			    pool->type, alloc_size);
		return ret;
	}

	return 0;
}

static struct mlx5hws_pool_elements *
hws_pool_element_create_new_elem(struct mlx5hws_pool *pool, u32 order)
static unsigned long *hws_pool_create_and_init_bitmap(u32 log_range)
{
	struct mlx5hws_pool_elements *elem;
	u32 alloc_size;

	alloc_size = pool->alloc_log_sz;

	elem = kzalloc(sizeof(*elem), GFP_KERNEL);
	if (!elem)
		return NULL;

	/* Sharing the same resource, also means that all the elements are with size 1 */
	if ((pool->flags & MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS) &&
	    !(pool->flags & MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK)) {
		 /* Currently all chunks in size 1 */
		elem->bitmap = hws_pool_create_and_init_bitmap(alloc_size - order);
		if (!elem->bitmap) {
			mlx5hws_err(pool->ctx,
				    "Failed to create bitmap type: %d: size %d\n",
				    pool->type, alloc_size);
			goto free_elem;
		}

		elem->log_size = alloc_size - order;
	}

	if (hws_pool_create_resource(pool, alloc_size)) {
		mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %d\n",
			    pool->type, alloc_size);
		goto free_db;
	}

	pool->db.element = elem;
	unsigned long *bitmap;

	return elem;

free_db:
	bitmap_free(elem->bitmap);
free_elem:
	kfree(elem);
	bitmap = bitmap_zalloc(1 << log_range, GFP_KERNEL);
	if (!bitmap)
		return NULL;
}

static int hws_pool_element_find_seg(struct mlx5hws_pool_elements *elem, int *seg)
{
	unsigned int segment, size;

	size = 1 << elem->log_size;
	bitmap_fill(bitmap, 1 << log_range);

	segment = find_first_bit(elem->bitmap, size);
	if (segment >= size) {
		elem->is_full = true;
		return -ENOMEM;
	}

	bitmap_clear(elem->bitmap, segment, 1);
	*seg = segment;
	return 0;
	return bitmap;
}

static int
hws_pool_onesize_element_get_mem_chunk(struct mlx5hws_pool *pool, u32 order,
				       int *seg)
static int hws_pool_bitmap_init(struct mlx5hws_pool *pool)
{
	struct mlx5hws_pool_elements *elem;
	unsigned long *bitmap;

	elem = pool->db.element;
	if (!elem)
		elem = hws_pool_element_create_new_elem(pool, order);
	if (!elem)
		goto err_no_elem;

	if (hws_pool_element_find_seg(elem, seg) != 0) {
		mlx5hws_err(pool->ctx, "No more resources (last request order: %d)\n", order);
	bitmap = hws_pool_create_and_init_bitmap(pool->alloc_log_sz);
	if (!bitmap) {
		mlx5hws_err(pool->ctx, "Failed to create bitmap order: %zu\n",
			    pool->alloc_log_sz);
		return -ENOMEM;
	}

	elem->num_of_elements++;
	return 0;

err_no_elem:
	mlx5hws_err(pool->ctx, "Failed to allocate element for order: %d\n", order);
	if (hws_pool_resource_alloc(pool) != 0) {
		mlx5hws_err(pool->ctx, "Failed to create resource type: %d: size %zu\n",
			    pool->type, pool->alloc_log_sz);
		bitmap_free(bitmap);
		return -ENOMEM;
	}

static int hws_pool_general_element_get_mem_chunk(struct mlx5hws_pool *pool,
						  u32 order, int *seg)
{
	int ret;
	pool->db.bitmap = bitmap;

	if (!pool->resource) {
		ret = hws_pool_create_resource(pool, order);
		if (ret)
			goto err_no_res;
		*seg = 0; /* One memory slot in that element */
	return 0;
}

	mlx5hws_err(pool->ctx, "No more resources (last request order: %d)\n", order);
	return -ENOMEM;

err_no_res:
	mlx5hws_err(pool->ctx, "Failed to allocate element for order: %d\n", order);
	return -ENOMEM;
}

static int hws_pool_general_element_db_get_chunk(struct mlx5hws_pool *pool,
static int hws_pool_bitmap_db_get_chunk(struct mlx5hws_pool *pool,
					struct mlx5hws_pool_chunk *chunk)
{
	int ret;
	unsigned long *bitmap, size;

	ret = hws_pool_general_element_get_mem_chunk(pool, chunk->order,
						     &chunk->offset);
	if (ret)
		mlx5hws_err(pool->ctx, "Failed to get free slot for chunk with order: %d\n",
			    chunk->order);

	return ret;
	if (chunk->order != 0) {
		mlx5hws_err(pool->ctx, "Pool only supports order 0 allocs\n");
		return -EINVAL;
	}

static void hws_pool_general_element_db_put_chunk(struct mlx5hws_pool *pool,
						  struct mlx5hws_pool_chunk *chunk)
{
	if (pool->flags & MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE)
		hws_pool_resource_free(pool);
	bitmap = pool->db.bitmap;
	if (!bitmap) {
		mlx5hws_err(pool->ctx, "Bad bitmap state\n");
		return -EINVAL;
	}

static void hws_pool_general_element_db_uninit(struct mlx5hws_pool *pool)
{
	(void)pool;
}
	size = 1 << pool->alloc_log_sz;

/* This memory management works as the following:
 * - At start doesn't allocate no mem at all.
 * - When new request for chunk arrived:
 *	allocate resource and give it.
 * - When free that chunk:
 *	the resource is freed.
 */
static int hws_pool_general_element_db_init(struct mlx5hws_pool *pool)
{
	pool->p_db_uninit = &hws_pool_general_element_db_uninit;
	pool->p_get_chunk = &hws_pool_general_element_db_get_chunk;
	pool->p_put_chunk = &hws_pool_general_element_db_put_chunk;
	chunk->offset = find_first_bit(bitmap, size);
	if (chunk->offset >= size)
		return -ENOMEM;

	return 0;
}
	bitmap_clear(bitmap, chunk->offset, 1);

static void
hws_onesize_element_db_destroy_element(struct mlx5hws_pool *pool,
				       struct mlx5hws_pool_elements *elem)
{
	hws_pool_resource_free(pool);
	bitmap_free(elem->bitmap);
	kfree(elem);
	pool->db.element = NULL;
	return 0;
}

static void hws_onesize_element_db_put_chunk(struct mlx5hws_pool *pool,
static void hws_pool_bitmap_db_put_chunk(struct mlx5hws_pool *pool,
					 struct mlx5hws_pool_chunk *chunk)
{
	struct mlx5hws_pool_elements *elem;
	unsigned long *bitmap;

	elem = pool->db.element;
	if (!elem) {
		mlx5hws_err(pool->ctx, "Pool element was not allocated\n");
	bitmap = pool->db.bitmap;
	if (!bitmap) {
		mlx5hws_err(pool->ctx, "Bad bitmap state\n");
		return;
	}

	bitmap_set(elem->bitmap, chunk->offset, 1);
	elem->is_full = false;
	elem->num_of_elements--;

	if (pool->flags & MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE &&
	    !elem->num_of_elements)
		hws_onesize_element_db_destroy_element(pool, elem);
	bitmap_set(bitmap, chunk->offset, 1);
}

static int hws_onesize_element_db_get_chunk(struct mlx5hws_pool *pool,
					    struct mlx5hws_pool_chunk *chunk)
static void hws_pool_bitmap_db_uninit(struct mlx5hws_pool *pool)
{
	int ret = 0;

	ret = hws_pool_onesize_element_get_mem_chunk(pool, chunk->order,
						     &chunk->offset);
	if (ret)
		mlx5hws_err(pool->ctx, "Failed to get free slot for chunk with order: %d\n",
			    chunk->order);
	unsigned long *bitmap;

	return ret;
	bitmap = pool->db.bitmap;
	if (bitmap) {
		bitmap_free(bitmap);
		pool->db.bitmap = NULL;
	}
}

static void hws_onesize_element_db_uninit(struct mlx5hws_pool *pool)
static int hws_pool_bitmap_db_init(struct mlx5hws_pool *pool)
{
	struct mlx5hws_pool_elements *elem = pool->db.element;
	int ret;

	if (elem) {
		bitmap_free(elem->bitmap);
		kfree(elem);
		pool->db.element = NULL;
	}
}
	ret = hws_pool_bitmap_init(pool);
	if (ret)
		return ret;

/* This memory management works as the following:
 * - At start doesn't allocate no mem at all.
 * - When new request for chunk arrived:
 *  aloocate the first and only slot of memory/resource
 *  when it ended return error.
 */
static int hws_pool_onesize_element_db_init(struct mlx5hws_pool *pool)
{
	pool->p_db_uninit = &hws_onesize_element_db_uninit;
	pool->p_get_chunk = &hws_onesize_element_db_get_chunk;
	pool->p_put_chunk = &hws_onesize_element_db_put_chunk;
	pool->p_db_uninit = &hws_pool_bitmap_db_uninit;
	pool->p_get_chunk = &hws_pool_bitmap_db_get_chunk;
	pool->p_put_chunk = &hws_pool_bitmap_db_put_chunk;

	return 0;
}
@@ -464,15 +298,14 @@ static int hws_pool_db_init(struct mlx5hws_pool *pool,
{
	int ret;

	if (db_type == MLX5HWS_POOL_DB_TYPE_GENERAL_SIZE)
		ret = hws_pool_general_element_db_init(pool);
	else if (db_type == MLX5HWS_POOL_DB_TYPE_ONE_SIZE_RESOURCE)
		ret = hws_pool_onesize_element_db_init(pool);
	if (db_type == MLX5HWS_POOL_DB_TYPE_BITMAP)
		ret = hws_pool_bitmap_db_init(pool);
	else
		ret = hws_pool_buddy_db_init(pool, pool->alloc_log_sz);
		ret = hws_pool_buddy_db_init(pool);

	if (ret) {
		mlx5hws_err(pool->ctx, "Failed to init general db : %d (ret: %d)\n", db_type, ret);
		mlx5hws_err(pool->ctx, "Failed to init pool type: %d (ret: %d)\n",
			    db_type, ret);
		return ret;
	}

@@ -521,15 +354,10 @@ mlx5hws_pool_create(struct mlx5hws_context *ctx, struct mlx5hws_pool_attr *pool_
	pool->tbl_type = pool_attr->table_type;
	pool->opt_type = pool_attr->opt_type;

	/* Support general db */
	if (pool->flags == (MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE |
			    MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK))
		res_db_type = MLX5HWS_POOL_DB_TYPE_GENERAL_SIZE;
	else if (pool->flags == (MLX5HWS_POOL_FLAGS_ONE_RESOURCE |
				 MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS))
		res_db_type = MLX5HWS_POOL_DB_TYPE_ONE_SIZE_RESOURCE;
	else
	if (pool->flags & MLX5HWS_POOL_FLAG_BUDDY)
		res_db_type = MLX5HWS_POOL_DB_TYPE_BUDDY;
	else
		res_db_type = MLX5HWS_POOL_DB_TYPE_BITMAP;

	pool->alloc_log_sz = pool_attr->alloc_log_sz;

@@ -545,7 +373,7 @@ mlx5hws_pool_create(struct mlx5hws_context *ctx, struct mlx5hws_pool_attr *pool_
	return NULL;
}

int mlx5hws_pool_destroy(struct mlx5hws_pool *pool)
void mlx5hws_pool_destroy(struct mlx5hws_pool *pool)
{
	mutex_destroy(&pool->lock);

@@ -555,5 +383,4 @@ int mlx5hws_pool_destroy(struct mlx5hws_pool *pool)
	hws_pool_db_unint(pool);

	kfree(pool);
	return 0;
}
+8 −37
Original line number Diff line number Diff line
@@ -23,29 +23,10 @@ struct mlx5hws_pool_resource {
};

enum mlx5hws_pool_flags {
	/* Only a one resource in that pool */
	MLX5HWS_POOL_FLAGS_ONE_RESOURCE = 1 << 0,
	MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE = 1 << 1,
	/* No sharing resources between chunks */
	MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK = 1 << 2,
	/* All objects are in the same size */
	MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS = 1 << 3,
	/* Managed by buddy allocator */
	MLX5HWS_POOL_FLAGS_BUDDY_MANAGED = 1 << 4,
	/* Allocate pool_type memory on pool creation */
	MLX5HWS_POOL_FLAGS_ALLOC_MEM_ON_CREATE = 1 << 5,

	/* These values should be used by the caller */
	MLX5HWS_POOL_FLAGS_FOR_STC_POOL =
		MLX5HWS_POOL_FLAGS_ONE_RESOURCE |
		MLX5HWS_POOL_FLAGS_FIXED_SIZE_OBJECTS,
	MLX5HWS_POOL_FLAGS_FOR_MATCHER_STE_POOL =
		MLX5HWS_POOL_FLAGS_RELEASE_FREE_RESOURCE |
		MLX5HWS_POOL_FLAGS_RESOURCE_PER_CHUNK,
	MLX5HWS_POOL_FLAGS_FOR_STE_ACTION_POOL =
		MLX5HWS_POOL_FLAGS_ONE_RESOURCE |
		MLX5HWS_POOL_FLAGS_BUDDY_MANAGED |
		MLX5HWS_POOL_FLAGS_ALLOC_MEM_ON_CREATE,
	/* Managed by a buddy allocator. If this is not set only allocations of
	 * order 0 are supported.
	 */
	MLX5HWS_POOL_FLAG_BUDDY = BIT(0),
};

enum mlx5hws_pool_optimize {
@@ -64,25 +45,16 @@ struct mlx5hws_pool_attr {
};

enum mlx5hws_db_type {
	/* Uses for allocating chunk of big memory, each element has its own resource in the FW*/
	MLX5HWS_POOL_DB_TYPE_GENERAL_SIZE,
	/* One resource only, all the elements are with same one size */
	MLX5HWS_POOL_DB_TYPE_ONE_SIZE_RESOURCE,
	/* Uses a bitmap, supports only allocations of order 0. */
	MLX5HWS_POOL_DB_TYPE_BITMAP,
	/* Entries are managed using a buddy mechanism. */
	MLX5HWS_POOL_DB_TYPE_BUDDY,
};

struct mlx5hws_pool_elements {
	u32 num_of_elements;
	unsigned long *bitmap;
	u32 log_size;
	bool is_full;
};

struct mlx5hws_pool_db {
	enum mlx5hws_db_type type;
	union {
		struct mlx5hws_pool_elements *element;
		unsigned long *bitmap;
		struct mlx5hws_buddy_mem *buddy;
	};
};
@@ -103,7 +75,6 @@ struct mlx5hws_pool {
	enum mlx5hws_pool_optimize opt_type;
	struct mlx5hws_pool_resource *resource;
	struct mlx5hws_pool_resource *mirror_resource;
	/* DB */
	struct mlx5hws_pool_db db;
	/* Functions */
	mlx5hws_pool_unint_db p_db_uninit;
@@ -115,7 +86,7 @@ struct mlx5hws_pool *
mlx5hws_pool_create(struct mlx5hws_context *ctx,
		    struct mlx5hws_pool_attr *pool_attr);

int mlx5hws_pool_destroy(struct mlx5hws_pool *pool);
void mlx5hws_pool_destroy(struct mlx5hws_pool *pool);

int mlx5hws_pool_chunk_alloc(struct mlx5hws_pool *pool,
			     struct mlx5hws_pool_chunk *chunk);