@@ -889,7 +889,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
889889 struct fs_node * iter = list_entry (start , struct fs_node , list );
890890 struct mlx5_flow_table * ft = NULL ;
891891
892- if (!root || root -> type == FS_TYPE_PRIO_CHAINS )
892+ if (!root )
893893 return NULL ;
894894
895895 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,
905905 return ft ;
906906}
907907
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.
911927 */
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 )
913930{
931+ struct fs_node * prio_chains_parent = NULL ;
914932 struct mlx5_flow_table * ft = NULL ;
915933 struct fs_node * curr_node ;
916934 struct fs_node * parent ;
917935
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 ;
920940 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 );
922944 curr_node = parent ;
923945 parent = curr_node -> parent ;
924946 }
925947 return ft ;
926948}
927949
928950/* 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 )
930952{
931- return find_closest_ft (prio , false);
953+ return find_closest_ft (node , false, true );
932954}
933955
934956/* 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 )
936958{
937- return find_closest_ft (prio , true);
959+ return find_closest_ft (node , true , true);
938960}
939961
940962static 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,
946968 next_ns = flow_act -> action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS ;
947969 fs_get_obj (prio , next_ns ? ft -> ns -> node .parent : ft -> node .parent );
948970
949- return find_next_chained_ft (prio );
971+ return find_next_chained_ft (& prio -> node );
950972}
951973
952974static 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,
970992 return 0 ;
971993}
972994
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+
9731010/* Connect flow tables from previous priority of prio to ft */
9741011static int connect_prev_fts (struct mlx5_core_dev * dev ,
9751012 struct mlx5_flow_table * ft ,
9761013 struct fs_prio * prio )
9771014{
1015+ struct fs_node * prio_parent , * parent = NULL , * child , * node ;
9781016 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 ;
9791024
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 ) {
9821027 struct fs_prio * prev_prio ;
9831028
9841029 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);
9861042 }
987- return 0 ;
1043+ return err ;
9881044}
9891045
9901046static 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
11231179 if (err )
11241180 return err ;
11251181
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 );
11271183 err = connect_fwd_rules (dev , ft , next_ft );
11281184 if (err )
11291185 return err ;
@@ -1198,7 +1254,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
11981254
11991255 tree_init_node (& ft -> node , del_hw_flow_table , del_sw_flow_table );
12001256 next_ft = unmanaged ? ft_attr -> next_ft :
1201- find_next_chained_ft (fs_prio );
1257+ find_next_chained_ft (& fs_prio -> node );
12021258 ft -> def_miss_action = ns -> def_miss_action ;
12031259 ft -> ns = ns ;
12041260 err = root -> cmds -> create_flow_table (root , ft , ft_attr , next_ft );
@@ -2195,13 +2251,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules);
21952251/* Assuming prio->node.children(flow tables) is sorted by level */
21962252static struct mlx5_flow_table * find_next_ft (struct mlx5_flow_table * ft )
21972253{
2254+ struct fs_node * prio_parent , * child ;
21982255 struct fs_prio * prio ;
21992256
22002257 fs_get_obj (prio , ft -> node .parent );
22012258
22022259 if (!list_is_last (& ft -> node .list , & prio -> node .children ))
22032260 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 );
22052268}
22062269
22072270static int update_root_ft_destroy (struct mlx5_flow_table * ft )
0 commit comments