761 lines
24 KiB
Diff
761 lines
24 KiB
Diff
From ac067697d1ab53a4dceeec03736f9b8bf2363665 Mon Sep 17 00:00:00 2001
|
|
From: Kamal Heib <kheib@redhat.com>
|
|
Date: Thu, 16 Apr 2026 17:41:59 -0400
|
|
Subject: [PATCH] net/mlx5: HWS, Refactor pool implementation
|
|
|
|
JIRA: https://redhat.atlassian.net/browse/RHEL-169055
|
|
|
|
commit d171ce3d988868bed9dc3c9eeb8428f87dd9ac85
|
|
Author: Vlad Dogaru <vdogaru@nvidia.com>
|
|
Date: Thu Apr 10 22:17:34 2025 +0300
|
|
|
|
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: Vlad Dogaru <vdogaru@nvidia.com>
|
|
Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
|
|
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
|
|
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
|
|
Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
|
|
Link: https://patch.msgid.link/1744312662-356571-5-git-send-email-tariqt@nvidia.com
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
|
|
Signed-off-by: Kamal Heib <kheib@redhat.com>
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
|
|
index 781ba8c4f733..39904b337b81 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
|
|
@@ -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) {
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c
|
|
index 9cda2774fd64..b7cb736b74d7 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c
|
|
@@ -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);
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c
|
|
index 59b14db427b4..95d31fd6c976 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c
|
|
@@ -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);
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
|
|
index 0de03e17624c..270b333faab3 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
|
|
@@ -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,
|
|
- struct mlx5hws_pool_chunk *chunk)
|
|
+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;
|
|
+ unsigned long *bitmap;
|
|
|
|
- elem = kzalloc(sizeof(*elem), GFP_KERNEL);
|
|
- if (!elem)
|
|
+ bitmap = bitmap_zalloc(1 << log_range, GFP_KERNEL);
|
|
+ if (!bitmap)
|
|
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;
|
|
+ bitmap_fill(bitmap, 1 << log_range);
|
|
|
|
- return elem;
|
|
-
|
|
-free_db:
|
|
- bitmap_free(elem->bitmap);
|
|
-free_elem:
|
|
- kfree(elem);
|
|
- return NULL;
|
|
+ return bitmap;
|
|
}
|
|
|
|
-static int hws_pool_element_find_seg(struct mlx5hws_pool_elements *elem, int *seg)
|
|
+static int hws_pool_bitmap_init(struct mlx5hws_pool *pool)
|
|
{
|
|
- unsigned int segment, size;
|
|
+ unsigned long *bitmap;
|
|
|
|
- size = 1 << elem->log_size;
|
|
-
|
|
- segment = find_first_bit(elem->bitmap, size);
|
|
- if (segment >= size) {
|
|
- elem->is_full = true;
|
|
+ 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;
|
|
}
|
|
|
|
- bitmap_clear(elem->bitmap, segment, 1);
|
|
- *seg = segment;
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static int
|
|
-hws_pool_onesize_element_get_mem_chunk(struct mlx5hws_pool *pool, u32 order,
|
|
- int *seg)
|
|
-{
|
|
- struct mlx5hws_pool_elements *elem;
|
|
-
|
|
- 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);
|
|
+ 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;
|
|
}
|
|
|
|
- elem->num_of_elements++;
|
|
- return 0;
|
|
+ pool->db.bitmap = bitmap;
|
|
|
|
-err_no_elem:
|
|
- mlx5hws_err(pool->ctx, "Failed to allocate element for order: %d\n", order);
|
|
- return -ENOMEM;
|
|
+ return 0;
|
|
}
|
|
|
|
-static int hws_pool_general_element_get_mem_chunk(struct mlx5hws_pool *pool,
|
|
- u32 order, int *seg)
|
|
+static int hws_pool_bitmap_db_get_chunk(struct mlx5hws_pool *pool,
|
|
+ struct mlx5hws_pool_chunk *chunk)
|
|
{
|
|
- int ret;
|
|
+ unsigned long *bitmap, size;
|
|
|
|
- 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;
|
|
+ if (chunk->order != 0) {
|
|
+ mlx5hws_err(pool->ctx, "Pool only supports order 0 allocs\n");
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
- 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,
|
|
- struct mlx5hws_pool_chunk *chunk)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- 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;
|
|
-}
|
|
+ bitmap = pool->db.bitmap;
|
|
+ if (!bitmap) {
|
|
+ mlx5hws_err(pool->ctx, "Bad bitmap state\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);
|
|
-}
|
|
+ size = 1 << pool->alloc_log_sz;
|
|
|
|
-static void hws_pool_general_element_db_uninit(struct mlx5hws_pool *pool)
|
|
-{
|
|
- (void)pool;
|
|
-}
|
|
+ chunk->offset = find_first_bit(bitmap, size);
|
|
+ if (chunk->offset >= size)
|
|
+ return -ENOMEM;
|
|
|
|
-/* 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;
|
|
+ bitmap_clear(bitmap, chunk->offset, 1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
-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;
|
|
-}
|
|
-
|
|
-static void hws_onesize_element_db_put_chunk(struct mlx5hws_pool *pool,
|
|
- struct mlx5hws_pool_chunk *chunk)
|
|
+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;
|
|
}
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.h
|
|
index 112a61cd2997..9a781a87f097 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.h
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.h
|
|
@@ -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);
|
|
--
|
|
2.50.1 (Apple Git-155)
|
|
|