From: Yevgeny Kliteynik <klit...@nvidia.com> Track buddy's used ICM memory, and free it if all of the buddy's memory bacame unused. Do this only for STEs. MODIFY_ACTION buddies are much smaller, so in case there is a large amount of modify_header actions, which result in large amount of MODIFY_ACTION buddies, doing this cleanup during sync will result in performance hit while not freeing significant amount of memory.
Signed-off-by: Yevgeny Kliteynik <klit...@nvidia.com> Reviewed-by: Alex Vesker <va...@nvidia.com> Reviewed-by: Mark Bloch <mbl...@nvidia.com> Signed-off-by: Saeed Mahameed <sae...@nvidia.com> --- .../mellanox/mlx5/core/steering/dr_icm_pool.c | 14 ++++++++++---- .../ethernet/mellanox/mlx5/core/steering/mlx5dr.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c index c49f8e86f3bc..66c24767e3b0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c @@ -175,10 +175,12 @@ get_chunk_icm_type(struct mlx5dr_icm_chunk *chunk) return chunk->buddy_mem->pool->icm_type; } -static void dr_icm_chunk_destroy(struct mlx5dr_icm_chunk *chunk) +static void dr_icm_chunk_destroy(struct mlx5dr_icm_chunk *chunk, + struct mlx5dr_icm_buddy_mem *buddy) { enum mlx5dr_icm_type icm_type = get_chunk_icm_type(chunk); + buddy->used_memory -= chunk->byte_size; list_del(&chunk->chunk_list); if (icm_type == DR_ICM_TYPE_STE) @@ -223,10 +225,10 @@ static void dr_icm_buddy_destroy(struct mlx5dr_icm_buddy_mem *buddy) struct mlx5dr_icm_chunk *chunk, *next; list_for_each_entry_safe(chunk, next, &buddy->hot_list, chunk_list) - dr_icm_chunk_destroy(chunk); + dr_icm_chunk_destroy(chunk, buddy); list_for_each_entry_safe(chunk, next, &buddy->used_list, chunk_list) - dr_icm_chunk_destroy(chunk); + dr_icm_chunk_destroy(chunk, buddy); dr_icm_pool_mr_destroy(buddy->icm_mr); @@ -267,6 +269,7 @@ dr_icm_chunk_create(struct mlx5dr_icm_pool *pool, goto out_free_chunk; } + buddy_mem_pool->used_memory += chunk->byte_size; chunk->buddy_mem = buddy_mem_pool; INIT_LIST_HEAD(&chunk->chunk_list); @@ -306,8 +309,11 @@ static int dr_icm_pool_sync_all_buddy_pools(struct mlx5dr_icm_pool *pool) mlx5dr_buddy_free_mem(buddy, chunk->seg, ilog2(chunk->num_of_entries)); pool->hot_memory_size -= chunk->byte_size; - dr_icm_chunk_destroy(chunk); + dr_icm_chunk_destroy(chunk, buddy); } + + if (!buddy->used_memory && pool->icm_type == DR_ICM_TYPE_STE) + dr_icm_buddy_destroy(buddy); } return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h index 93ddb9c3e6b6..0aaba0ae9cf7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h @@ -141,6 +141,7 @@ struct mlx5dr_icm_buddy_mem { /* This is the list of used chunks. HW may be accessing this memory */ struct list_head used_list; + u64 used_memory; /* Hardware may be accessing this memory but at some future, * undetermined time, it might cease to do so. -- 2.26.2