History

net/mlx5: Use aligned variable while allocating ICM memory

The alignment value is part of the input structure, so use it and spare extra memory allocation when is not needed. Now, using the new ability when allocating icm for Direct-Rule insertion. Signed-off-by: Ariel Levkovich <lariel@mellanox.com> Signed-off-by: Erez Shitrit <erezsh@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>

Erez Shitrit committed 6 years ago

Commit dff8e2d1 parent 2b58f6d4 files · +38 −35Browse files

Unified · Split

4 files
  1. drivers/infiniband/hw/mlx5/main.c +1 −1
  2. drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c +10 −5
  3. drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c +25 −28
  4. include/linux/mlx5/driver.h +2 −1
drivers/infiniband/hw/mlx5/main.c+1−1
@@ -2444,7 +2444,7 @@ static int handle_alloc_dm_sw_icm(struct ib_ucontext *ctx, · 2443 unmodified lines
2444 act_size = roundup_pow_of_two(act_size);2444 act_size = roundup_pow_of_two(act_size);
2445 2445
2446 dm->size = act_size;2446 dm->size = act_size;
2447 err = mlx5_dm_sw_icm_alloc(dev, type, act_size,2447 err = mlx5_dm_sw_icm_alloc(dev, type, act_size, attr->alignment,
2448 to_mucontext(ctx)->devx_uid, &dm->dev_addr,2448 to_mucontext(ctx)->devx_uid, &dm->dev_addr,
2449 &dm->icm_dm.obj_id);2449 &dm->icm_dm.obj_id);
2450 if (err)2450 if (err)
drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c+10−5
@@ -90,7 +90,8 @@ void mlx5_dm_cleanup(struct mlx5_core_dev *dev) · 89 unmodified lines
90}90}
91 91
92int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type,92int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type,
93 u64 length, u16 uid, phys_addr_t *addr, u32 *obj_id)93 u64 length, u32 log_alignment, u16 uid,
94 phys_addr_t *addr, u32 *obj_id)
94{95{
95 u32 num_blocks = DIV_ROUND_UP_ULL(length, MLX5_SW_ICM_BLOCK_SIZE(dev));96 u32 num_blocks = DIV_ROUND_UP_ULL(length, MLX5_SW_ICM_BLOCK_SIZE(dev));
96 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};97 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
@@ -99,6 +100,7 @@ int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type, · 2 unmodified lines
99 unsigned long *block_map;100 unsigned long *block_map;
100 u64 icm_start_addr;101 u64 icm_start_addr;
101 u32 log_icm_size;102 u32 log_icm_size;
103 u64 align_mask;
102 u32 max_blocks;104 u32 max_blocks;
103 u64 block_idx;105 u64 block_idx;
104 void *sw_icm;106 void *sw_icm;
@@ -136,11 +138,14 @@ int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type, · 31 unmodified lines
136 return -EOPNOTSUPP;138 return -EOPNOTSUPP;
137 139
138 max_blocks = BIT(log_icm_size - MLX5_LOG_SW_ICM_BLOCK_SIZE(dev));140 max_blocks = BIT(log_icm_size - MLX5_LOG_SW_ICM_BLOCK_SIZE(dev));
141
142 if (log_alignment < MLX5_LOG_SW_ICM_BLOCK_SIZE(dev))
143 log_alignment = MLX5_LOG_SW_ICM_BLOCK_SIZE(dev);
144 align_mask = BIT(log_alignment - MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)) - 1;
145
139 spin_lock(&dm->lock);146 spin_lock(&dm->lock);
140 block_idx = bitmap_find_next_zero_area(block_map,147 block_idx = bitmap_find_next_zero_area(block_map, max_blocks, 0,
141 max_blocks,148 num_blocks, align_mask);
142 0,
143 num_blocks, 0);
144 149
145 if (block_idx < max_blocks)150 if (block_idx < max_blocks)
146 bitmap_set(block_map,151 bitmap_set(block_map,
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_icm_pool.c+25−28
@@ -95,13 +95,12 @@ static int dr_icm_create_dm_mkey(struct mlx5_core_dev *mdev, · 94 unmodified lines
95}95}
96 96
97static struct mlx5dr_icm_mr *97static struct mlx5dr_icm_mr *
98dr_icm_pool_mr_create(struct mlx5dr_icm_pool *pool,98dr_icm_pool_mr_create(struct mlx5dr_icm_pool *pool)
99 enum mlx5_sw_icm_type type,
100 size_t align_base)
101{99{
102 struct mlx5_core_dev *mdev = pool->dmn->mdev;100 struct mlx5_core_dev *mdev = pool->dmn->mdev;
101 enum mlx5_sw_icm_type dm_type;
103 struct mlx5dr_icm_mr *icm_mr;102 struct mlx5dr_icm_mr *icm_mr;
104 size_t align_diff;103 size_t log_align_base;
105 int err;104 int err;
106 105
107 icm_mr = kvzalloc(sizeof(*icm_mr), GFP_KERNEL);106 icm_mr = kvzalloc(sizeof(*icm_mr), GFP_KERNEL);
@@ -111,14 +110,22 @@ dr_icm_pool_mr_create(struct mlx5dr_icm_pool *pool, · 3 unmodified lines
111 icm_mr->pool = pool;110 icm_mr->pool = pool;
112 INIT_LIST_HEAD(&icm_mr->mr_list);111 INIT_LIST_HEAD(&icm_mr->mr_list);
113 112
114 icm_mr->dm.type = type;
115
116 /* 2^log_biggest_table * entry-size * double-for-alignment */
117 icm_mr->dm.length = mlx5dr_icm_pool_chunk_size_to_byte(pool->max_log_chunk_sz,113 icm_mr->dm.length = mlx5dr_icm_pool_chunk_size_to_byte(pool->max_log_chunk_sz,
118 pool->icm_type) * 2;114 pool->icm_type);
115
116 if (pool->icm_type == DR_ICM_TYPE_STE) {
117 dm_type = MLX5_SW_ICM_TYPE_STEERING;
118 log_align_base = ilog2(icm_mr->dm.length);
119 } else {
120 dm_type = MLX5_SW_ICM_TYPE_HEADER_MODIFY;
121 /* Align base is 64B */
122 log_align_base = ilog2(DR_ICM_MODIFY_HDR_ALIGN_BASE);
123 }
124 icm_mr->dm.type = dm_type;
119 125
120 err = mlx5_dm_sw_icm_alloc(mdev, icm_mr->dm.type, icm_mr->dm.length, 0,126 err = mlx5_dm_sw_icm_alloc(mdev, icm_mr->dm.type, icm_mr->dm.length,
121 &icm_mr->dm.addr, &icm_mr->dm.obj_id);127 log_align_base, 0, &icm_mr->dm.addr,
128 &icm_mr->dm.obj_id);
122 if (err) {129 if (err) {
123 mlx5dr_err(pool->dmn, "Failed to allocate SW ICM memory, err (%d)\n", err);130 mlx5dr_err(pool->dmn, "Failed to allocate SW ICM memory, err (%d)\n", err);
124 goto free_icm_mr;131 goto free_icm_mr;
@@ -137,15 +144,18 @@ dr_icm_pool_mr_create(struct mlx5dr_icm_pool *pool, · 12 unmodified lines
137 144
138 icm_mr->icm_start_addr = icm_mr->dm.addr;145 icm_mr->icm_start_addr = icm_mr->dm.addr;
139 146
140 /* align_base is always a power of 2 */147 if (icm_mr->icm_start_addr & (BIT(log_align_base) - 1)) {
141 align_diff = icm_mr->icm_start_addr & (align_base - 1);148 mlx5dr_err(pool->dmn, "Failed to get Aligned ICM mem (asked: %zu)\n",
142 if (align_diff)149 log_align_base);
143 icm_mr->used_length = align_base - align_diff;150 goto free_mkey;
151 }
144 152
145 list_add_tail(&icm_mr->mr_list, &pool->icm_mr_list);153 list_add_tail(&icm_mr->mr_list, &pool->icm_mr_list);
146 154
147 return icm_mr;155 return icm_mr;
148 156
157free_mkey:
158 mlx5_core_destroy_mkey(mdev, &icm_mr->mkey);
149free_dm:159free_dm:
150 mlx5_dm_sw_icm_dealloc(mdev, icm_mr->dm.type, icm_mr->dm.length, 0,160 mlx5_dm_sw_icm_dealloc(mdev, icm_mr->dm.type, icm_mr->dm.length, 0,
151 icm_mr->dm.addr, icm_mr->dm.obj_id);161 icm_mr->dm.addr, icm_mr->dm.obj_id);
@@ -200,24 +210,11 @@ static int dr_icm_chunks_create(struct mlx5dr_icm_bucket *bucket) · 48 unmodified lines
200 struct mlx5dr_icm_pool *pool = bucket->pool;210 struct mlx5dr_icm_pool *pool = bucket->pool;
201 struct mlx5dr_icm_mr *icm_mr = NULL;211 struct mlx5dr_icm_mr *icm_mr = NULL;
202 struct mlx5dr_icm_chunk *chunk;212 struct mlx5dr_icm_chunk *chunk;
203 enum mlx5_sw_icm_type dm_type;
204 size_t align_base;
205 int i, err = 0;213 int i, err = 0;
206 214
207 mr_req_size = bucket->num_of_entries * bucket->entry_size;215 mr_req_size = bucket->num_of_entries * bucket->entry_size;
208 mr_row_size = mlx5dr_icm_pool_chunk_size_to_byte(pool->max_log_chunk_sz,216 mr_row_size = mlx5dr_icm_pool_chunk_size_to_byte(pool->max_log_chunk_sz,
209 pool->icm_type);217 pool->icm_type);
210
211 if (pool->icm_type == DR_ICM_TYPE_STE) {
212 dm_type = MLX5_SW_ICM_TYPE_STEERING;
213 /* Align base is the biggest chunk size / row size */
214 align_base = mr_row_size;
215 } else {
216 dm_type = MLX5_SW_ICM_TYPE_HEADER_MODIFY;
217 /* Align base is 64B */
218 align_base = DR_ICM_MODIFY_HDR_ALIGN_BASE;
219 }
220
221 mutex_lock(&pool->mr_mutex);218 mutex_lock(&pool->mr_mutex);
222 if (!list_empty(&pool->icm_mr_list)) {219 if (!list_empty(&pool->icm_mr_list)) {
223 icm_mr = list_last_entry(&pool->icm_mr_list,220 icm_mr = list_last_entry(&pool->icm_mr_list,
@@ -228,7 +225,7 @@ static int dr_icm_chunks_create(struct mlx5dr_icm_bucket *bucket) · 4 unmodified lines
228 }225 }
229 226
230 if (!icm_mr || mr_free_size < mr_row_size) {227 if (!icm_mr || mr_free_size < mr_row_size) {
231 icm_mr = dr_icm_pool_mr_create(pool, dm_type, align_base);228 icm_mr = dr_icm_pool_mr_create(pool);
232 if (!icm_mr) {229 if (!icm_mr) {
233 err = -ENOMEM;230 err = -ENOMEM;
234 goto out_err;231 goto out_err;
include/linux/mlx5/driver.h+2−1
@@ -1080,7 +1080,8 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, · 1079 unmodified lines
1080struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);1080struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);
1081void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);1081void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);
1082int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type,1082int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type,
1083 u64 length, u16 uid, phys_addr_t *addr, u32 *obj_id);1083 u64 length, u32 log_alignment, u16 uid,
1084 phys_addr_t *addr, u32 *obj_id);
1084int mlx5_dm_sw_icm_dealloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type,1085int mlx5_dm_sw_icm_dealloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type,
1085 u64 length, u16 uid, phys_addr_t addr, u32 obj_id);1086 u64 length, u16 uid, phys_addr_t addr, u32 obj_id);
1086 1087