Skip to content

Commit b36315c

Browse files
mosheshemesh2kuba-moo
authored andcommitted
net/mlx5: fs, add HWS modify header API function
Add modify header alloc and dealloc API functions to provide modify header actions for steering rules. Use fs hws pools to get actions from shared bulks of modify header actions. Signed-off-by: Moshe Shemesh <[email protected]> Reviewed-by: Yevgeny Kliteynik <[email protected]> Reviewed-by: Mark Bloch <[email protected]> Signed-off-by: Tariq Toukan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent aecd9d1 commit b36315c

File tree

5 files changed

+310
-0
lines changed

5 files changed

+310
-0
lines changed

drivers/net/ethernet/mellanox/mlx5/core/fs_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct mlx5_modify_hdr {
6565
enum mlx5_flow_resource_owner owner;
6666
union {
6767
struct mlx5_fs_dr_action fs_dr_action;
68+
struct mlx5_fs_hws_action fs_hws_action;
6869
u32 id;
6970
};
7071
};

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ mlx5_fs_create_action_remove_header_vlan(struct mlx5hws_context *ctx);
1515
static void
1616
mlx5_fs_destroy_pr_pool(struct mlx5_fs_pool *pool, struct xarray *pr_pools,
1717
unsigned long index);
18+
static void
19+
mlx5_fs_destroy_mh_pool(struct mlx5_fs_pool *pool, struct xarray *mh_pools,
20+
unsigned long index);
1821

1922
static int mlx5_fs_init_hws_actions_pool(struct mlx5_core_dev *dev,
2023
struct mlx5_fs_hws_context *fs_ctx)
@@ -58,6 +61,7 @@ static int mlx5_fs_init_hws_actions_pool(struct mlx5_core_dev *dev,
5861
goto cleanup_insert_hdr;
5962
xa_init(&hws_pool->el2tol3tnl_pools);
6063
xa_init(&hws_pool->el2tol2tnl_pools);
64+
xa_init(&hws_pool->mh_pools);
6165
return 0;
6266

6367
cleanup_insert_hdr:
@@ -83,6 +87,9 @@ static void mlx5_fs_cleanup_hws_actions_pool(struct mlx5_fs_hws_context *fs_ctx)
8387
struct mlx5_fs_pool *pool;
8488
unsigned long i;
8589

90+
xa_for_each(&hws_pool->mh_pools, i, pool)
91+
mlx5_fs_destroy_mh_pool(pool, &hws_pool->mh_pools, i);
92+
xa_destroy(&hws_pool->mh_pools);
8693
xa_for_each(&hws_pool->el2tol2tnl_pools, i, pool)
8794
mlx5_fs_destroy_pr_pool(pool, &hws_pool->el2tol2tnl_pools, i);
8895
xa_destroy(&hws_pool->el2tol2tnl_pools);
@@ -532,6 +539,117 @@ static void mlx5_cmd_hws_packet_reformat_dealloc(struct mlx5_flow_root_namespace
532539
pkt_reformat->fs_hws_action.pr_data = NULL;
533540
}
534541

542+
static struct mlx5_fs_pool *
543+
mlx5_fs_create_mh_pool(struct mlx5_core_dev *dev,
544+
struct mlx5hws_action_mh_pattern *pattern,
545+
struct xarray *mh_pools, unsigned long index)
546+
{
547+
struct mlx5_fs_pool *pool;
548+
int err;
549+
550+
pool = kzalloc(sizeof(*pool), GFP_KERNEL);
551+
if (!pool)
552+
return ERR_PTR(-ENOMEM);
553+
err = mlx5_fs_hws_mh_pool_init(pool, dev, pattern);
554+
if (err)
555+
goto free_pool;
556+
err = xa_insert(mh_pools, index, pool, GFP_KERNEL);
557+
if (err)
558+
goto cleanup_pool;
559+
return pool;
560+
561+
cleanup_pool:
562+
mlx5_fs_hws_mh_pool_cleanup(pool);
563+
free_pool:
564+
kfree(pool);
565+
return ERR_PTR(err);
566+
}
567+
568+
static void
569+
mlx5_fs_destroy_mh_pool(struct mlx5_fs_pool *pool, struct xarray *mh_pools,
570+
unsigned long index)
571+
{
572+
xa_erase(mh_pools, index);
573+
mlx5_fs_hws_mh_pool_cleanup(pool);
574+
kfree(pool);
575+
}
576+
577+
static int mlx5_cmd_hws_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
578+
u8 namespace, u8 num_actions,
579+
void *modify_actions,
580+
struct mlx5_modify_hdr *modify_hdr)
581+
{
582+
struct mlx5_fs_hws_actions_pool *hws_pool = &ns->fs_hws_context.hws_pool;
583+
struct mlx5hws_action_mh_pattern pattern = {};
584+
struct mlx5_fs_hws_mh *mh_data = NULL;
585+
struct mlx5hws_action *hws_action;
586+
struct mlx5_fs_pool *pool;
587+
unsigned long i, cnt = 0;
588+
bool known_pattern;
589+
int err;
590+
591+
pattern.sz = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto) * num_actions;
592+
pattern.data = modify_actions;
593+
594+
known_pattern = false;
595+
xa_for_each(&hws_pool->mh_pools, i, pool) {
596+
if (mlx5_fs_hws_mh_pool_match(pool, &pattern)) {
597+
known_pattern = true;
598+
break;
599+
}
600+
cnt++;
601+
}
602+
603+
if (!known_pattern) {
604+
pool = mlx5_fs_create_mh_pool(ns->dev, &pattern,
605+
&hws_pool->mh_pools, cnt);
606+
if (IS_ERR(pool))
607+
return PTR_ERR(pool);
608+
}
609+
mh_data = mlx5_fs_hws_mh_pool_acquire_mh(pool);
610+
if (IS_ERR(mh_data)) {
611+
err = PTR_ERR(mh_data);
612+
goto destroy_pool;
613+
}
614+
hws_action = mh_data->bulk->hws_action;
615+
mh_data->data = kmemdup(pattern.data, pattern.sz, GFP_KERNEL);
616+
if (!mh_data->data) {
617+
err = -ENOMEM;
618+
goto release_mh;
619+
}
620+
modify_hdr->fs_hws_action.mh_data = mh_data;
621+
modify_hdr->fs_hws_action.fs_pool = pool;
622+
modify_hdr->owner = MLX5_FLOW_RESOURCE_OWNER_SW;
623+
modify_hdr->fs_hws_action.hws_action = hws_action;
624+
625+
return 0;
626+
627+
release_mh:
628+
mlx5_fs_hws_mh_pool_release_mh(pool, mh_data);
629+
destroy_pool:
630+
if (!known_pattern)
631+
mlx5_fs_destroy_mh_pool(pool, &hws_pool->mh_pools, cnt);
632+
return err;
633+
}
634+
635+
static void mlx5_cmd_hws_modify_header_dealloc(struct mlx5_flow_root_namespace *ns,
636+
struct mlx5_modify_hdr *modify_hdr)
637+
{
638+
struct mlx5_fs_hws_mh *mh_data;
639+
struct mlx5_fs_pool *pool;
640+
641+
if (!modify_hdr->fs_hws_action.fs_pool || !modify_hdr->fs_hws_action.mh_data) {
642+
mlx5_core_err(ns->dev, "Failed release modify-header\n");
643+
return;
644+
}
645+
646+
mh_data = modify_hdr->fs_hws_action.mh_data;
647+
kfree(mh_data->data);
648+
pool = modify_hdr->fs_hws_action.fs_pool;
649+
mlx5_fs_hws_mh_pool_release_mh(pool, mh_data);
650+
modify_hdr->fs_hws_action.mh_data = NULL;
651+
}
652+
535653
static const struct mlx5_flow_cmds mlx5_flow_cmds_hws = {
536654
.create_flow_table = mlx5_cmd_hws_create_flow_table,
537655
.destroy_flow_table = mlx5_cmd_hws_destroy_flow_table,
@@ -541,6 +659,8 @@ static const struct mlx5_flow_cmds mlx5_flow_cmds_hws = {
541659
.destroy_flow_group = mlx5_cmd_hws_destroy_flow_group,
542660
.packet_reformat_alloc = mlx5_cmd_hws_packet_reformat_alloc,
543661
.packet_reformat_dealloc = mlx5_cmd_hws_packet_reformat_dealloc,
662+
.modify_header_alloc = mlx5_cmd_hws_modify_header_alloc,
663+
.modify_header_dealloc = mlx5_cmd_hws_modify_header_dealloc,
544664
.create_ns = mlx5_cmd_hws_create_ns,
545665
.destroy_ns = mlx5_cmd_hws_destroy_ns,
546666
.set_peer = mlx5_cmd_hws_set_peer,

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct mlx5_fs_hws_actions_pool {
1818
struct mlx5_fs_pool dl3tnltol2_pool;
1919
struct xarray el2tol3tnl_pools;
2020
struct xarray el2tol2tnl_pools;
21+
struct xarray mh_pools;
2122
};
2223

2324
struct mlx5_fs_hws_context {
@@ -34,6 +35,7 @@ struct mlx5_fs_hws_action {
3435
struct mlx5hws_action *hws_action;
3536
struct mlx5_fs_pool *fs_pool;
3637
struct mlx5_fs_hws_pr *pr_data;
38+
struct mlx5_fs_hws_mh *mh_data;
3739
};
3840

3941
struct mlx5_fs_hws_matcher {

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws_pools.c

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,168 @@ struct mlx5hws_action *mlx5_fs_hws_pr_get_action(struct mlx5_fs_hws_pr *pr_data)
236236
{
237237
return pr_data->bulk->hws_action;
238238
}
239+
240+
static struct mlx5hws_action *
241+
mlx5_fs_mh_bulk_action_create(struct mlx5hws_context *ctx,
242+
struct mlx5hws_action_mh_pattern *pattern)
243+
{
244+
u32 flags = MLX5HWS_ACTION_FLAG_HWS_FDB;
245+
u32 log_bulk_size;
246+
247+
log_bulk_size = ilog2(MLX5_FS_HWS_DEFAULT_BULK_LEN);
248+
return mlx5hws_action_create_modify_header(ctx, 1, pattern,
249+
log_bulk_size, flags);
250+
}
251+
252+
static struct mlx5_fs_bulk *
253+
mlx5_fs_hws_mh_bulk_create(struct mlx5_core_dev *dev, void *pool_ctx)
254+
{
255+
struct mlx5hws_action_mh_pattern *pattern;
256+
struct mlx5_flow_root_namespace *root_ns;
257+
struct mlx5_fs_hws_mh_bulk *mh_bulk;
258+
struct mlx5hws_context *ctx;
259+
int bulk_len;
260+
261+
if (!pool_ctx)
262+
return NULL;
263+
264+
root_ns = mlx5_get_root_namespace(dev, MLX5_FLOW_NAMESPACE_FDB);
265+
if (!root_ns || root_ns->mode != MLX5_FLOW_STEERING_MODE_HMFS)
266+
return NULL;
267+
268+
ctx = root_ns->fs_hws_context.hws_ctx;
269+
if (!ctx)
270+
return NULL;
271+
272+
pattern = pool_ctx;
273+
bulk_len = MLX5_FS_HWS_DEFAULT_BULK_LEN;
274+
mh_bulk = kvzalloc(struct_size(mh_bulk, mhs_data, bulk_len), GFP_KERNEL);
275+
if (!mh_bulk)
276+
return NULL;
277+
278+
if (mlx5_fs_bulk_init(dev, &mh_bulk->fs_bulk, bulk_len))
279+
goto free_mh_bulk;
280+
281+
for (int i = 0; i < bulk_len; i++) {
282+
mh_bulk->mhs_data[i].bulk = mh_bulk;
283+
mh_bulk->mhs_data[i].offset = i;
284+
}
285+
286+
mh_bulk->hws_action = mlx5_fs_mh_bulk_action_create(ctx, pattern);
287+
if (!mh_bulk->hws_action)
288+
goto cleanup_fs_bulk;
289+
290+
return &mh_bulk->fs_bulk;
291+
292+
cleanup_fs_bulk:
293+
mlx5_fs_bulk_cleanup(&mh_bulk->fs_bulk);
294+
free_mh_bulk:
295+
kvfree(mh_bulk);
296+
return NULL;
297+
}
298+
299+
static int
300+
mlx5_fs_hws_mh_bulk_destroy(struct mlx5_core_dev *dev,
301+
struct mlx5_fs_bulk *fs_bulk)
302+
{
303+
struct mlx5_fs_hws_mh_bulk *mh_bulk;
304+
305+
mh_bulk = container_of(fs_bulk, struct mlx5_fs_hws_mh_bulk, fs_bulk);
306+
if (mlx5_fs_bulk_get_free_amount(fs_bulk) < fs_bulk->bulk_len) {
307+
mlx5_core_err(dev, "Freeing bulk before all modify header were released\n");
308+
return -EBUSY;
309+
}
310+
311+
mlx5hws_action_destroy(mh_bulk->hws_action);
312+
mlx5_fs_bulk_cleanup(fs_bulk);
313+
kvfree(mh_bulk);
314+
315+
return 0;
316+
}
317+
318+
static const struct mlx5_fs_pool_ops mlx5_fs_hws_mh_pool_ops = {
319+
.bulk_create = mlx5_fs_hws_mh_bulk_create,
320+
.bulk_destroy = mlx5_fs_hws_mh_bulk_destroy,
321+
.update_threshold = mlx5_hws_pool_update_threshold,
322+
};
323+
324+
int mlx5_fs_hws_mh_pool_init(struct mlx5_fs_pool *fs_hws_mh_pool,
325+
struct mlx5_core_dev *dev,
326+
struct mlx5hws_action_mh_pattern *pattern)
327+
{
328+
struct mlx5hws_action_mh_pattern *pool_pattern;
329+
330+
pool_pattern = kzalloc(sizeof(*pool_pattern), GFP_KERNEL);
331+
if (!pool_pattern)
332+
return -ENOMEM;
333+
pool_pattern->data = kmemdup(pattern->data, pattern->sz, GFP_KERNEL);
334+
if (!pool_pattern->data) {
335+
kfree(pool_pattern);
336+
return -ENOMEM;
337+
}
338+
pool_pattern->sz = pattern->sz;
339+
mlx5_fs_pool_init(fs_hws_mh_pool, dev, &mlx5_fs_hws_mh_pool_ops,
340+
pool_pattern);
341+
return 0;
342+
}
343+
344+
void mlx5_fs_hws_mh_pool_cleanup(struct mlx5_fs_pool *fs_hws_mh_pool)
345+
{
346+
struct mlx5hws_action_mh_pattern *pool_pattern;
347+
348+
mlx5_fs_pool_cleanup(fs_hws_mh_pool);
349+
pool_pattern = fs_hws_mh_pool->pool_ctx;
350+
if (!pool_pattern)
351+
return;
352+
kfree(pool_pattern->data);
353+
kfree(pool_pattern);
354+
}
355+
356+
struct mlx5_fs_hws_mh *
357+
mlx5_fs_hws_mh_pool_acquire_mh(struct mlx5_fs_pool *mh_pool)
358+
{
359+
struct mlx5_fs_pool_index pool_index = {};
360+
struct mlx5_fs_hws_mh_bulk *mh_bulk;
361+
int err;
362+
363+
err = mlx5_fs_pool_acquire_index(mh_pool, &pool_index);
364+
if (err)
365+
return ERR_PTR(err);
366+
mh_bulk = container_of(pool_index.fs_bulk, struct mlx5_fs_hws_mh_bulk,
367+
fs_bulk);
368+
return &mh_bulk->mhs_data[pool_index.index];
369+
}
370+
371+
void mlx5_fs_hws_mh_pool_release_mh(struct mlx5_fs_pool *mh_pool,
372+
struct mlx5_fs_hws_mh *mh_data)
373+
{
374+
struct mlx5_fs_bulk *fs_bulk = &mh_data->bulk->fs_bulk;
375+
struct mlx5_fs_pool_index pool_index = {};
376+
struct mlx5_core_dev *dev = mh_pool->dev;
377+
378+
pool_index.fs_bulk = fs_bulk;
379+
pool_index.index = mh_data->offset;
380+
if (mlx5_fs_pool_release_index(mh_pool, &pool_index))
381+
mlx5_core_warn(dev, "Attempted to release modify header which is not acquired\n");
382+
}
383+
384+
bool mlx5_fs_hws_mh_pool_match(struct mlx5_fs_pool *mh_pool,
385+
struct mlx5hws_action_mh_pattern *pattern)
386+
{
387+
struct mlx5hws_action_mh_pattern *pool_pattern;
388+
int num_actions, i;
389+
390+
pool_pattern = mh_pool->pool_ctx;
391+
if (WARN_ON_ONCE(!pool_pattern))
392+
return false;
393+
394+
if (pattern->sz != pool_pattern->sz)
395+
return false;
396+
num_actions = pattern->sz / MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto);
397+
for (i = 0; i < num_actions; i++) {
398+
if ((__force __be32)pattern->data[i] !=
399+
(__force __be32)pool_pattern->data[i])
400+
return false;
401+
}
402+
return true;
403+
}

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws_pools.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ struct mlx5_fs_hws_pr_pool_ctx {
3636
size_t encap_data_size;
3737
};
3838

39+
struct mlx5_fs_hws_mh {
40+
struct mlx5_fs_hws_mh_bulk *bulk;
41+
u32 offset;
42+
u8 *data;
43+
};
44+
45+
struct mlx5_fs_hws_mh_bulk {
46+
struct mlx5_fs_bulk fs_bulk;
47+
struct mlx5_fs_pool *mh_pool;
48+
struct mlx5hws_action *hws_action;
49+
struct mlx5_fs_hws_mh mhs_data[];
50+
};
51+
3952
int mlx5_fs_hws_pr_pool_init(struct mlx5_fs_pool *pr_pool,
4053
struct mlx5_core_dev *dev, size_t encap_data_size,
4154
enum mlx5hws_action_type reformat_type);
@@ -45,4 +58,13 @@ struct mlx5_fs_hws_pr *mlx5_fs_hws_pr_pool_acquire_pr(struct mlx5_fs_pool *pr_po
4558
void mlx5_fs_hws_pr_pool_release_pr(struct mlx5_fs_pool *pr_pool,
4659
struct mlx5_fs_hws_pr *pr_data);
4760
struct mlx5hws_action *mlx5_fs_hws_pr_get_action(struct mlx5_fs_hws_pr *pr_data);
61+
int mlx5_fs_hws_mh_pool_init(struct mlx5_fs_pool *fs_hws_mh_pool,
62+
struct mlx5_core_dev *dev,
63+
struct mlx5hws_action_mh_pattern *pattern);
64+
void mlx5_fs_hws_mh_pool_cleanup(struct mlx5_fs_pool *fs_hws_mh_pool);
65+
struct mlx5_fs_hws_mh *mlx5_fs_hws_mh_pool_acquire_mh(struct mlx5_fs_pool *mh_pool);
66+
void mlx5_fs_hws_mh_pool_release_mh(struct mlx5_fs_pool *mh_pool,
67+
struct mlx5_fs_hws_mh *mh_data);
68+
bool mlx5_fs_hws_mh_pool_match(struct mlx5_fs_pool *mh_pool,
69+
struct mlx5hws_action_mh_pattern *pattern);
4870
#endif /* __MLX5_FS_HWS_POOLS_H__ */

0 commit comments

Comments
 (0)