@@ -889,7 +889,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
889
889
struct fs_node * iter = list_entry (start , struct fs_node , list );
890
890
struct mlx5_flow_table * ft = NULL ;
891
891
892
- if (!root || root -> type == FS_TYPE_PRIO_CHAINS )
892
+ if (!root )
893
893
return NULL ;
894
894
895
895
list_for_each_advance_continue (iter , & root -> children , reverse ) {
@@ -905,36 +905,58 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
905
905
return ft ;
906
906
}
907
907
908
- /* If reverse is false then return the first flow table in next priority of
909
- * prio in the tree, else return the last flow table in the previous priority
910
- * of prio in the tree.
908
+ static struct fs_node * find_prio_chains_parent (struct fs_node * parent ,
909
+ struct fs_node * * child )
910
+ {
911
+ struct fs_node * node = NULL ;
912
+
913
+ while (parent && parent -> type != FS_TYPE_PRIO_CHAINS ) {
914
+ node = parent ;
915
+ parent = parent -> parent ;
916
+ }
917
+
918
+ if (child )
919
+ * child = node ;
920
+
921
+ return parent ;
922
+ }
923
+
924
+ /* If reverse is false then return the first flow table next to the passed node
925
+ * in the tree, else return the last flow table before the node in the tree.
926
+ * If skip is true, skip the flow tables in the same prio_chains prio.
911
927
*/
912
- static struct mlx5_flow_table * find_closest_ft (struct fs_prio * prio , bool reverse )
928
+ static struct mlx5_flow_table * find_closest_ft (struct fs_node * node , bool reverse ,
929
+ bool skip )
913
930
{
931
+ struct fs_node * prio_chains_parent = NULL ;
914
932
struct mlx5_flow_table * ft = NULL ;
915
933
struct fs_node * curr_node ;
916
934
struct fs_node * parent ;
917
935
918
- parent = prio -> node .parent ;
919
- curr_node = & prio -> node ;
936
+ if (skip )
937
+ prio_chains_parent = find_prio_chains_parent (node , NULL );
938
+ parent = node -> parent ;
939
+ curr_node = node ;
920
940
while (!ft && parent ) {
921
- ft = find_closest_ft_recursive (parent , & curr_node -> list , reverse );
941
+ if (parent != prio_chains_parent )
942
+ ft = find_closest_ft_recursive (parent , & curr_node -> list ,
943
+ reverse );
922
944
curr_node = parent ;
923
945
parent = curr_node -> parent ;
924
946
}
925
947
return ft ;
926
948
}
927
949
928
950
/* Assuming all the tree is locked by mutex chain lock */
929
- static struct mlx5_flow_table * find_next_chained_ft (struct fs_prio * prio )
951
+ static struct mlx5_flow_table * find_next_chained_ft (struct fs_node * node )
930
952
{
931
- return find_closest_ft (prio , false);
953
+ return find_closest_ft (node , false, true );
932
954
}
933
955
934
956
/* Assuming all the tree is locked by mutex chain lock */
935
- static struct mlx5_flow_table * find_prev_chained_ft (struct fs_prio * prio )
957
+ static struct mlx5_flow_table * find_prev_chained_ft (struct fs_node * node )
936
958
{
937
- return find_closest_ft (prio , true);
959
+ return find_closest_ft (node , true , true);
938
960
}
939
961
940
962
static struct mlx5_flow_table * find_next_fwd_ft (struct mlx5_flow_table * ft ,
@@ -946,7 +968,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
946
968
next_ns = flow_act -> action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS ;
947
969
fs_get_obj (prio , next_ns ? ft -> ns -> node .parent : ft -> node .parent );
948
970
949
- return find_next_chained_ft (prio );
971
+ return find_next_chained_ft (& prio -> node );
950
972
}
951
973
952
974
static int connect_fts_in_prio (struct mlx5_core_dev * dev ,
@@ -970,21 +992,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
970
992
return 0 ;
971
993
}
972
994
995
+ static struct mlx5_flow_table * find_closet_ft_prio_chains (struct fs_node * node ,
996
+ struct fs_node * parent ,
997
+ struct fs_node * * child ,
998
+ bool reverse )
999
+ {
1000
+ struct mlx5_flow_table * ft ;
1001
+
1002
+ ft = find_closest_ft (node , reverse , false);
1003
+
1004
+ if (ft && parent == find_prio_chains_parent (& ft -> node , child ))
1005
+ return ft ;
1006
+
1007
+ return NULL ;
1008
+ }
1009
+
973
1010
/* Connect flow tables from previous priority of prio to ft */
974
1011
static int connect_prev_fts (struct mlx5_core_dev * dev ,
975
1012
struct mlx5_flow_table * ft ,
976
1013
struct fs_prio * prio )
977
1014
{
1015
+ struct fs_node * prio_parent , * parent = NULL , * child , * node ;
978
1016
struct mlx5_flow_table * prev_ft ;
1017
+ int err = 0 ;
1018
+
1019
+ prio_parent = find_prio_chains_parent (& prio -> node , & child );
1020
+
1021
+ /* return directly if not under the first sub ns of prio_chains prio */
1022
+ if (prio_parent && !list_is_first (& child -> list , & prio_parent -> children ))
1023
+ return 0 ;
979
1024
980
- prev_ft = find_prev_chained_ft (prio );
981
- if (prev_ft ) {
1025
+ prev_ft = find_prev_chained_ft (& prio -> node );
1026
+ while (prev_ft ) {
982
1027
struct fs_prio * prev_prio ;
983
1028
984
1029
fs_get_obj (prev_prio , prev_ft -> node .parent );
985
- return connect_fts_in_prio (dev , prev_prio , ft );
1030
+ err = connect_fts_in_prio (dev , prev_prio , ft );
1031
+ if (err )
1032
+ break ;
1033
+
1034
+ if (!parent ) {
1035
+ parent = find_prio_chains_parent (& prev_prio -> node , & child );
1036
+ if (!parent )
1037
+ break ;
1038
+ }
1039
+
1040
+ node = child ;
1041
+ prev_ft = find_closet_ft_prio_chains (node , parent , & child , true);
986
1042
}
987
- return 0 ;
1043
+ return err ;
988
1044
}
989
1045
990
1046
static int update_root_ft_create (struct mlx5_flow_table * ft , struct fs_prio
@@ -1123,7 +1179,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table
1123
1179
if (err )
1124
1180
return err ;
1125
1181
1126
- next_ft = first_ft ? first_ft : find_next_chained_ft (prio );
1182
+ next_ft = first_ft ? first_ft : find_next_chained_ft (& prio -> node );
1127
1183
err = connect_fwd_rules (dev , ft , next_ft );
1128
1184
if (err )
1129
1185
return err ;
@@ -1198,7 +1254,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
1198
1254
1199
1255
tree_init_node (& ft -> node , del_hw_flow_table , del_sw_flow_table );
1200
1256
next_ft = unmanaged ? ft_attr -> next_ft :
1201
- find_next_chained_ft (fs_prio );
1257
+ find_next_chained_ft (& fs_prio -> node );
1202
1258
ft -> def_miss_action = ns -> def_miss_action ;
1203
1259
ft -> ns = ns ;
1204
1260
err = root -> cmds -> create_flow_table (root , ft , ft_attr , next_ft );
@@ -2195,13 +2251,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules);
2195
2251
/* Assuming prio->node.children(flow tables) is sorted by level */
2196
2252
static struct mlx5_flow_table * find_next_ft (struct mlx5_flow_table * ft )
2197
2253
{
2254
+ struct fs_node * prio_parent , * child ;
2198
2255
struct fs_prio * prio ;
2199
2256
2200
2257
fs_get_obj (prio , ft -> node .parent );
2201
2258
2202
2259
if (!list_is_last (& ft -> node .list , & prio -> node .children ))
2203
2260
return list_next_entry (ft , node .list );
2204
- return find_next_chained_ft (prio );
2261
+
2262
+ prio_parent = find_prio_chains_parent (& prio -> node , & child );
2263
+
2264
+ if (prio_parent && list_is_first (& child -> list , & prio_parent -> children ))
2265
+ return find_closest_ft (& prio -> node , false, false);
2266
+
2267
+ return find_next_chained_ft (& prio -> node );
2205
2268
}
2206
2269
2207
2270
static int update_root_ft_destroy (struct mlx5_flow_table * ft )
0 commit comments