1
1
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2
2
/* Copyright (c) 2025 NVIDIA Corporation & Affiliates */
3
3
4
+ #include <linux/mlx5/vport.h>
4
5
#include <mlx5_core.h>
5
6
#include <fs_core.h>
6
7
#include <fs_cmd.h>
@@ -63,6 +64,8 @@ static int mlx5_fs_init_hws_actions_pool(struct mlx5_core_dev *dev,
63
64
xa_init (& hws_pool -> el2tol2tnl_pools );
64
65
xa_init (& hws_pool -> mh_pools );
65
66
xa_init (& hws_pool -> table_dests );
67
+ xa_init (& hws_pool -> vport_dests );
68
+ xa_init (& hws_pool -> vport_vhca_dests );
66
69
return 0 ;
67
70
68
71
cleanup_insert_hdr :
@@ -85,9 +88,16 @@ static int mlx5_fs_init_hws_actions_pool(struct mlx5_core_dev *dev,
85
88
static void mlx5_fs_cleanup_hws_actions_pool (struct mlx5_fs_hws_context * fs_ctx )
86
89
{
87
90
struct mlx5_fs_hws_actions_pool * hws_pool = & fs_ctx -> hws_pool ;
91
+ struct mlx5hws_action * action ;
88
92
struct mlx5_fs_pool * pool ;
89
93
unsigned long i ;
90
94
95
+ xa_for_each (& hws_pool -> vport_vhca_dests , i , action )
96
+ mlx5hws_action_destroy (action );
97
+ xa_destroy (& hws_pool -> vport_vhca_dests );
98
+ xa_for_each (& hws_pool -> vport_dests , i , action )
99
+ mlx5hws_action_destroy (action );
100
+ xa_destroy (& hws_pool -> vport_dests );
91
101
xa_destroy (& hws_pool -> table_dests );
92
102
xa_for_each (& hws_pool -> mh_pools , i , pool )
93
103
mlx5_fs_destroy_mh_pool (pool , & hws_pool -> mh_pools , i );
@@ -387,6 +397,52 @@ mlx5_fs_create_dest_action_table_num(struct mlx5_fs_hws_context *fs_ctx,
387
397
return mlx5hws_action_create_dest_table_num (ctx , table_num , flags );
388
398
}
389
399
400
+ static struct mlx5hws_action *
401
+ mlx5_fs_get_dest_action_vport (struct mlx5_fs_hws_context * fs_ctx ,
402
+ struct mlx5_flow_rule * dst ,
403
+ bool is_dest_type_uplink )
404
+ {
405
+ u32 flags = MLX5HWS_ACTION_FLAG_HWS_FDB | MLX5HWS_ACTION_FLAG_SHARED ;
406
+ struct mlx5_flow_destination * dest_attr = & dst -> dest_attr ;
407
+ struct mlx5hws_context * ctx = fs_ctx -> hws_ctx ;
408
+ struct mlx5hws_action * dest ;
409
+ struct xarray * dests_xa ;
410
+ bool vhca_id_valid ;
411
+ unsigned long idx ;
412
+ u16 vport_num ;
413
+ int err ;
414
+
415
+ vhca_id_valid = is_dest_type_uplink ||
416
+ (dest_attr -> vport .flags & MLX5_FLOW_DEST_VPORT_VHCA_ID );
417
+ vport_num = is_dest_type_uplink ? MLX5_VPORT_UPLINK : dest_attr -> vport .num ;
418
+ if (vhca_id_valid ) {
419
+ dests_xa = & fs_ctx -> hws_pool .vport_vhca_dests ;
420
+ idx = dest_attr -> vport .vhca_id << 16 | vport_num ;
421
+ } else {
422
+ dests_xa = & fs_ctx -> hws_pool .vport_dests ;
423
+ idx = vport_num ;
424
+ }
425
+ dest_load :
426
+ dest = xa_load (dests_xa , idx );
427
+ if (dest )
428
+ return dest ;
429
+
430
+ dest = mlx5hws_action_create_dest_vport (ctx , vport_num , vhca_id_valid ,
431
+ dest_attr -> vport .vhca_id , flags );
432
+
433
+ err = xa_insert (dests_xa , idx , dest , GFP_KERNEL );
434
+ if (err ) {
435
+ mlx5hws_action_destroy (dest );
436
+ dest = NULL ;
437
+
438
+ if (err == - EBUSY )
439
+ /* xarray entry was already stored by another thread */
440
+ goto dest_load ;
441
+ }
442
+
443
+ return dest ;
444
+ }
445
+
390
446
static struct mlx5hws_action *
391
447
mlx5_fs_create_dest_action_range (struct mlx5hws_context * ctx ,
392
448
struct mlx5_flow_rule * dst )
@@ -695,6 +751,8 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
695
751
if (fte_action -> action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ) {
696
752
list_for_each_entry (dst , & fte -> node .children , node .list ) {
697
753
struct mlx5_flow_destination * attr = & dst -> dest_attr ;
754
+ bool type_uplink =
755
+ attr -> type == MLX5_FLOW_DESTINATION_TYPE_UPLINK ;
698
756
699
757
if (num_fs_actions == MLX5_FLOW_CONTEXT_ACTION_MAX ||
700
758
num_dest_actions == MLX5_FLOW_CONTEXT_ACTION_MAX ) {
@@ -721,6 +779,11 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
721
779
dest_action = mlx5_fs_create_dest_action_range (ctx , dst );
722
780
fs_actions [num_fs_actions ++ ].action = dest_action ;
723
781
break ;
782
+ case MLX5_FLOW_DESTINATION_TYPE_UPLINK :
783
+ case MLX5_FLOW_DESTINATION_TYPE_VPORT :
784
+ dest_action = mlx5_fs_get_dest_action_vport (fs_ctx , dst ,
785
+ type_uplink );
786
+ break ;
724
787
default :
725
788
err = - EOPNOTSUPP ;
726
789
goto free_actions ;
0 commit comments