@@ -679,7 +679,15 @@ enum flow_table_type {
679679#define MLX5_FS_MAX_TYPES 6
680680#define MLX5_FS_MAX_ENTRIES BIT(16)
681681
682- static struct mlx5_ib_flow_prio * _get_prio (struct mlx5_flow_namespace * ns ,
682+ static bool mlx5_ib_shared_ft_allowed (struct ib_device * device )
683+ {
684+ struct mlx5_ib_dev * dev = to_mdev (device );
685+
686+ return MLX5_CAP_GEN (dev -> mdev , shared_object_to_user_object_allowed );
687+ }
688+
689+ static struct mlx5_ib_flow_prio * _get_prio (struct mlx5_ib_dev * dev ,
690+ struct mlx5_flow_namespace * ns ,
683691 struct mlx5_ib_flow_prio * prio ,
684692 int priority ,
685693 int num_entries , int num_groups ,
@@ -688,6 +696,8 @@ static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_flow_namespace *ns,
688696 struct mlx5_flow_table_attr ft_attr = {};
689697 struct mlx5_flow_table * ft ;
690698
699+ if (mlx5_ib_shared_ft_allowed (& dev -> ib_dev ))
700+ ft_attr .uid = MLX5_SHARED_RESOURCE_UID ;
691701 ft_attr .prio = priority ;
692702 ft_attr .max_fte = num_entries ;
693703 ft_attr .flags = flags ;
@@ -784,8 +794,8 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
784794
785795 ft = prio -> flow_table ;
786796 if (!ft )
787- return _get_prio (ns , prio , priority , max_table_size , num_groups ,
788- flags );
797+ return _get_prio (dev , ns , prio , priority , max_table_size ,
798+ num_groups , flags );
789799
790800 return prio ;
791801}
@@ -927,7 +937,7 @@ int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num,
927937
928938 prio = & dev -> flow_db -> opfcs [type ];
929939 if (!prio -> flow_table ) {
930- prio = _get_prio (ns , prio , priority ,
940+ prio = _get_prio (dev , ns , prio , priority ,
931941 dev -> num_ports * MAX_OPFC_RULES , 1 , 0 );
932942 if (IS_ERR (prio )) {
933943 err = PTR_ERR (prio );
@@ -1407,8 +1417,8 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
14071417}
14081418
14091419static struct mlx5_ib_flow_prio *
1410- _get_flow_table (struct mlx5_ib_dev * dev ,
1411- struct mlx5_ib_flow_matcher * fs_matcher ,
1420+ _get_flow_table (struct mlx5_ib_dev * dev , u16 user_priority ,
1421+ enum mlx5_flow_namespace_type ns_type ,
14121422 bool mcast )
14131423{
14141424 struct mlx5_flow_namespace * ns = NULL ;
@@ -1421,11 +1431,11 @@ _get_flow_table(struct mlx5_ib_dev *dev,
14211431 if (mcast )
14221432 priority = MLX5_IB_FLOW_MCAST_PRIO ;
14231433 else
1424- priority = ib_prio_to_core_prio (fs_matcher -> priority , false);
1434+ priority = ib_prio_to_core_prio (user_priority , false);
14251435
14261436 esw_encap = mlx5_eswitch_get_encap_mode (dev -> mdev ) !=
14271437 DEVLINK_ESWITCH_ENCAP_MODE_NONE ;
1428- switch (fs_matcher -> ns_type ) {
1438+ switch (ns_type ) {
14291439 case MLX5_FLOW_NAMESPACE_BYPASS :
14301440 max_table_size = BIT (
14311441 MLX5_CAP_FLOWTABLE_NIC_RX (dev -> mdev , log_max_ft_size ));
@@ -1452,29 +1462,29 @@ _get_flow_table(struct mlx5_ib_dev *dev,
14521462 reformat_l3_tunnel_to_l2 ) &&
14531463 esw_encap )
14541464 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT ;
1455- priority = fs_matcher -> priority ;
1465+ priority = user_priority ;
14561466 break ;
14571467 case MLX5_FLOW_NAMESPACE_RDMA_RX :
14581468 max_table_size = BIT (
14591469 MLX5_CAP_FLOWTABLE_RDMA_RX (dev -> mdev , log_max_ft_size ));
1460- priority = fs_matcher -> priority ;
1470+ priority = user_priority ;
14611471 break ;
14621472 case MLX5_FLOW_NAMESPACE_RDMA_TX :
14631473 max_table_size = BIT (
14641474 MLX5_CAP_FLOWTABLE_RDMA_TX (dev -> mdev , log_max_ft_size ));
1465- priority = fs_matcher -> priority ;
1475+ priority = user_priority ;
14661476 break ;
14671477 default :
14681478 break ;
14691479 }
14701480
14711481 max_table_size = min_t (int , max_table_size , MLX5_FS_MAX_ENTRIES );
14721482
1473- ns = mlx5_get_flow_namespace (dev -> mdev , fs_matcher -> ns_type );
1483+ ns = mlx5_get_flow_namespace (dev -> mdev , ns_type );
14741484 if (!ns )
14751485 return ERR_PTR (- EOPNOTSUPP );
14761486
1477- switch (fs_matcher -> ns_type ) {
1487+ switch (ns_type ) {
14781488 case MLX5_FLOW_NAMESPACE_BYPASS :
14791489 prio = & dev -> flow_db -> prios [priority ];
14801490 break ;
@@ -1499,7 +1509,7 @@ _get_flow_table(struct mlx5_ib_dev *dev,
14991509 if (prio -> flow_table )
15001510 return prio ;
15011511
1502- return _get_prio (ns , prio , priority , max_table_size ,
1512+ return _get_prio (dev , ns , prio , priority , max_table_size ,
15031513 MLX5_FS_MAX_TYPES , flags );
15041514}
15051515
@@ -1618,7 +1628,8 @@ static struct mlx5_ib_flow_handler *raw_fs_rule_add(
16181628 mcast = raw_fs_is_multicast (fs_matcher , cmd_in );
16191629 mutex_lock (& dev -> flow_db -> lock );
16201630
1621- ft_prio = _get_flow_table (dev , fs_matcher , mcast );
1631+ ft_prio = _get_flow_table (dev , fs_matcher -> priority ,
1632+ fs_matcher -> ns_type , mcast );
16221633 if (IS_ERR (ft_prio )) {
16231634 err = PTR_ERR (ft_prio );
16241635 goto unlock ;
@@ -2015,6 +2026,23 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject,
20152026 return 0 ;
20162027}
20172028
2029+ static int steering_anchor_cleanup (struct ib_uobject * uobject ,
2030+ enum rdma_remove_reason why ,
2031+ struct uverbs_attr_bundle * attrs )
2032+ {
2033+ struct mlx5_ib_steering_anchor * obj = uobject -> object ;
2034+
2035+ if (atomic_read (& obj -> usecnt ))
2036+ return - EBUSY ;
2037+
2038+ mutex_lock (& obj -> dev -> flow_db -> lock );
2039+ put_flow_table (obj -> dev , obj -> ft_prio , true);
2040+ mutex_unlock (& obj -> dev -> flow_db -> lock );
2041+
2042+ kfree (obj );
2043+ return 0 ;
2044+ }
2045+
20182046static int mlx5_ib_matcher_ns (struct uverbs_attr_bundle * attrs ,
20192047 struct mlx5_ib_flow_matcher * obj )
20202048{
@@ -2050,12 +2078,10 @@ static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
20502078 if (err )
20512079 return err ;
20522080
2053- if (flags ) {
2054- mlx5_ib_ft_type_to_namespace (
2081+ if (flags )
2082+ return mlx5_ib_ft_type_to_namespace (
20552083 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX ,
20562084 & obj -> ns_type );
2057- return 0 ;
2058- }
20592085 }
20602086
20612087 obj -> ns_type = MLX5_FLOW_NAMESPACE_BYPASS ;
@@ -2121,6 +2147,75 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
21212147 return err ;
21222148}
21232149
2150+ static int UVERBS_HANDLER (MLX5_IB_METHOD_STEERING_ANCHOR_CREATE )(
2151+ struct uverbs_attr_bundle * attrs )
2152+ {
2153+ struct ib_uobject * uobj = uverbs_attr_get_uobject (
2154+ attrs , MLX5_IB_ATTR_STEERING_ANCHOR_CREATE_HANDLE );
2155+ struct mlx5_ib_dev * dev = mlx5_udata_to_mdev (& attrs -> driver_udata );
2156+ enum mlx5_ib_uapi_flow_table_type ib_uapi_ft_type ;
2157+ enum mlx5_flow_namespace_type ns_type ;
2158+ struct mlx5_ib_steering_anchor * obj ;
2159+ struct mlx5_ib_flow_prio * ft_prio ;
2160+ u16 priority ;
2161+ u32 ft_id ;
2162+ int err ;
2163+
2164+ if (!capable (CAP_NET_RAW ))
2165+ return - EPERM ;
2166+
2167+ err = uverbs_get_const (& ib_uapi_ft_type , attrs ,
2168+ MLX5_IB_ATTR_STEERING_ANCHOR_FT_TYPE );
2169+ if (err )
2170+ return err ;
2171+
2172+ err = mlx5_ib_ft_type_to_namespace (ib_uapi_ft_type , & ns_type );
2173+ if (err )
2174+ return err ;
2175+
2176+ err = uverbs_copy_from (& priority , attrs ,
2177+ MLX5_IB_ATTR_STEERING_ANCHOR_PRIORITY );
2178+ if (err )
2179+ return err ;
2180+
2181+ obj = kzalloc (sizeof (* obj ), GFP_KERNEL );
2182+ if (!obj )
2183+ return - ENOMEM ;
2184+
2185+ mutex_lock (& dev -> flow_db -> lock );
2186+ ft_prio = _get_flow_table (dev , priority , ns_type , 0 );
2187+ if (IS_ERR (ft_prio )) {
2188+ mutex_unlock (& dev -> flow_db -> lock );
2189+ err = PTR_ERR (ft_prio );
2190+ goto free_obj ;
2191+ }
2192+
2193+ ft_prio -> refcount ++ ;
2194+ ft_id = mlx5_flow_table_id (ft_prio -> flow_table );
2195+ mutex_unlock (& dev -> flow_db -> lock );
2196+
2197+ err = uverbs_copy_to (attrs , MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID ,
2198+ & ft_id , sizeof (ft_id ));
2199+ if (err )
2200+ goto put_flow_table ;
2201+
2202+ uobj -> object = obj ;
2203+ obj -> dev = dev ;
2204+ obj -> ft_prio = ft_prio ;
2205+ atomic_set (& obj -> usecnt , 0 );
2206+
2207+ return 0 ;
2208+
2209+ put_flow_table :
2210+ mutex_lock (& dev -> flow_db -> lock );
2211+ put_flow_table (dev , ft_prio , true);
2212+ mutex_unlock (& dev -> flow_db -> lock );
2213+ free_obj :
2214+ kfree (obj );
2215+
2216+ return err ;
2217+ }
2218+
21242219static struct ib_flow_action *
21252220mlx5_ib_create_modify_header (struct mlx5_ib_dev * dev ,
21262221 enum mlx5_ib_uapi_flow_table_type ft_type ,
@@ -2477,6 +2572,35 @@ DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER,
24772572 & UVERBS_METHOD (MLX5_IB_METHOD_FLOW_MATCHER_CREATE ),
24782573 & UVERBS_METHOD (MLX5_IB_METHOD_FLOW_MATCHER_DESTROY ));
24792574
2575+ DECLARE_UVERBS_NAMED_METHOD (
2576+ MLX5_IB_METHOD_STEERING_ANCHOR_CREATE ,
2577+ UVERBS_ATTR_IDR (MLX5_IB_ATTR_STEERING_ANCHOR_CREATE_HANDLE ,
2578+ MLX5_IB_OBJECT_STEERING_ANCHOR ,
2579+ UVERBS_ACCESS_NEW ,
2580+ UA_MANDATORY ),
2581+ UVERBS_ATTR_CONST_IN (MLX5_IB_ATTR_STEERING_ANCHOR_FT_TYPE ,
2582+ enum mlx5_ib_uapi_flow_table_type ,
2583+ UA_MANDATORY ),
2584+ UVERBS_ATTR_PTR_IN (MLX5_IB_ATTR_STEERING_ANCHOR_PRIORITY ,
2585+ UVERBS_ATTR_TYPE (u16 ),
2586+ UA_MANDATORY ),
2587+ UVERBS_ATTR_PTR_IN (MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID ,
2588+ UVERBS_ATTR_TYPE (u32 ),
2589+ UA_MANDATORY ));
2590+
2591+ DECLARE_UVERBS_NAMED_METHOD_DESTROY (
2592+ MLX5_IB_METHOD_STEERING_ANCHOR_DESTROY ,
2593+ UVERBS_ATTR_IDR (MLX5_IB_ATTR_STEERING_ANCHOR_DESTROY_HANDLE ,
2594+ MLX5_IB_OBJECT_STEERING_ANCHOR ,
2595+ UVERBS_ACCESS_DESTROY ,
2596+ UA_MANDATORY ));
2597+
2598+ DECLARE_UVERBS_NAMED_OBJECT (
2599+ MLX5_IB_OBJECT_STEERING_ANCHOR ,
2600+ UVERBS_TYPE_ALLOC_IDR (steering_anchor_cleanup ),
2601+ & UVERBS_METHOD (MLX5_IB_METHOD_STEERING_ANCHOR_CREATE ),
2602+ & UVERBS_METHOD (MLX5_IB_METHOD_STEERING_ANCHOR_DESTROY ));
2603+
24802604const struct uapi_definition mlx5_ib_flow_defs [] = {
24812605 UAPI_DEF_CHAIN_OBJ_TREE_NAMED (
24822606 MLX5_IB_OBJECT_FLOW_MATCHER ),
@@ -2485,6 +2609,9 @@ const struct uapi_definition mlx5_ib_flow_defs[] = {
24852609 & mlx5_ib_fs ),
24862610 UAPI_DEF_CHAIN_OBJ_TREE (UVERBS_OBJECT_FLOW_ACTION ,
24872611 & mlx5_ib_flow_actions ),
2612+ UAPI_DEF_CHAIN_OBJ_TREE_NAMED (
2613+ MLX5_IB_OBJECT_STEERING_ANCHOR ,
2614+ UAPI_DEF_IS_OBJ_SUPPORTED (mlx5_ib_shared_ft_allowed )),
24882615 {},
24892616};
24902617
0 commit comments