@@ -263,10 +263,11 @@ static void nested_down_write_ref_node(struct fs_node *node,
263263 }
264264}
265265
266- static void down_write_ref_node (struct fs_node * node )
266+ static void down_write_ref_node (struct fs_node * node , bool locked )
267267{
268268 if (node ) {
269- down_write (& node -> lock );
269+ if (!locked )
270+ down_write (& node -> lock );
270271 refcount_inc (& node -> refcount );
271272 }
272273}
@@ -277,13 +278,14 @@ static void up_read_ref_node(struct fs_node *node)
277278 up_read (& node -> lock );
278279}
279280
280- static void up_write_ref_node (struct fs_node * node )
281+ static void up_write_ref_node (struct fs_node * node , bool locked )
281282{
282283 refcount_dec (& node -> refcount );
283- up_write (& node -> lock );
284+ if (!locked )
285+ up_write (& node -> lock );
284286}
285287
286- static void tree_put_node (struct fs_node * node )
288+ static void tree_put_node (struct fs_node * node , bool locked )
287289{
288290 struct fs_node * parent_node = node -> parent ;
289291
@@ -294,27 +296,27 @@ static void tree_put_node(struct fs_node *node)
294296 /* Only root namespace doesn't have parent and we just
295297 * need to free its node.
296298 */
297- down_write_ref_node (parent_node );
299+ down_write_ref_node (parent_node , locked );
298300 list_del_init (& node -> list );
299301 if (node -> del_sw_func )
300302 node -> del_sw_func (node );
301- up_write_ref_node (parent_node );
303+ up_write_ref_node (parent_node , locked );
302304 } else {
303305 kfree (node );
304306 }
305307 node = NULL ;
306308 }
307309 if (!node && parent_node )
308- tree_put_node (parent_node );
310+ tree_put_node (parent_node , locked );
309311}
310312
311- static int tree_remove_node (struct fs_node * node )
313+ static int tree_remove_node (struct fs_node * node , bool locked )
312314{
313315 if (refcount_read (& node -> refcount ) > 1 ) {
314316 refcount_dec (& node -> refcount );
315317 return - EEXIST ;
316318 }
317- tree_put_node (node );
319+ tree_put_node (node , locked );
318320 return 0 ;
319321}
320322
@@ -867,15 +869,15 @@ static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
867869 fs_get_obj (fte , rule -> node .parent );
868870 if (!(fte -> action .action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ))
869871 return - EINVAL ;
870- down_write_ref_node (& fte -> node );
872+ down_write_ref_node (& fte -> node , false );
871873 fs_get_obj (fg , fte -> node .parent );
872874 fs_get_obj (ft , fg -> node .parent );
873875
874876 memcpy (& rule -> dest_attr , dest , sizeof (* dest ));
875877 root = find_root (& ft -> node );
876878 err = root -> cmds -> update_fte (get_dev (& ft -> node ), ft , fg -> id ,
877879 modify_mask , fte );
878- up_write_ref_node (& fte -> node );
880+ up_write_ref_node (& fte -> node , false );
879881
880882 return err ;
881883}
@@ -1025,11 +1027,11 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
10251027 if (err )
10261028 goto destroy_ft ;
10271029 ft -> node .active = true;
1028- down_write_ref_node (& fs_prio -> node );
1030+ down_write_ref_node (& fs_prio -> node , false );
10291031 tree_add_node (& ft -> node , & fs_prio -> node );
10301032 list_add_flow_table (ft , fs_prio );
10311033 fs_prio -> num_ft ++ ;
1032- up_write_ref_node (& fs_prio -> node );
1034+ up_write_ref_node (& fs_prio -> node , false );
10331035 mutex_unlock (& root -> chain_lock );
10341036 trace_mlx5_fs_add_ft (ft );
10351037 return ft ;
@@ -1123,17 +1125,17 @@ struct mlx5_flow_group *mlx5_create_flow_group(struct mlx5_flow_table *ft,
11231125 if (ft -> autogroup .active )
11241126 return ERR_PTR (- EPERM );
11251127
1126- down_write_ref_node (& ft -> node );
1128+ down_write_ref_node (& ft -> node , false );
11271129 fg = alloc_insert_flow_group (ft , match_criteria_enable , match_criteria ,
11281130 start_index , end_index ,
11291131 ft -> node .children .prev );
1130- up_write_ref_node (& ft -> node );
1132+ up_write_ref_node (& ft -> node , false );
11311133 if (IS_ERR (fg ))
11321134 return fg ;
11331135
11341136 err = root -> cmds -> create_flow_group (dev , ft , fg_in , & fg -> id );
11351137 if (err ) {
1136- tree_put_node (& fg -> node );
1138+ tree_put_node (& fg -> node , false );
11371139 return ERR_PTR (err );
11381140 }
11391141 trace_mlx5_fs_add_fg (fg );
@@ -1530,10 +1532,10 @@ static void free_match_list(struct match_list_head *head)
15301532 struct match_list * iter , * match_tmp ;
15311533
15321534 list_del (& head -> first .list );
1533- tree_put_node (& head -> first .g -> node );
1535+ tree_put_node (& head -> first .g -> node , false );
15341536 list_for_each_entry_safe (iter , match_tmp , & head -> list ,
15351537 list ) {
1536- tree_put_node (& iter -> g -> node );
1538+ tree_put_node (& iter -> g -> node , false );
15371539 list_del (& iter -> list );
15381540 kfree (iter );
15391541 }
@@ -1611,15 +1613,15 @@ lookup_fte_locked(struct mlx5_flow_group *g,
16111613 goto out ;
16121614 }
16131615 if (!fte_tmp -> node .active ) {
1614- tree_put_node (& fte_tmp -> node );
1616+ tree_put_node (& fte_tmp -> node , false );
16151617 fte_tmp = NULL ;
16161618 goto out ;
16171619 }
16181620
16191621 nested_down_write_ref_node (& fte_tmp -> node , FS_LOCK_CHILD );
16201622out :
16211623 if (take_write )
1622- up_write_ref_node (& g -> node );
1624+ up_write_ref_node (& g -> node , false );
16231625 else
16241626 up_read_ref_node (& g -> node );
16251627 return fte_tmp ;
@@ -1661,8 +1663,8 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
16611663 continue ;
16621664 rule = add_rule_fg (g , spec -> match_value ,
16631665 flow_act , dest , dest_num , fte_tmp );
1664- up_write_ref_node (& fte_tmp -> node );
1665- tree_put_node (& fte_tmp -> node );
1666+ up_write_ref_node (& fte_tmp -> node , false );
1667+ tree_put_node (& fte_tmp -> node , false );
16661668 kmem_cache_free (steering -> ftes_cache , fte );
16671669 return rule ;
16681670 }
@@ -1698,19 +1700,19 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
16981700
16991701 err = insert_fte (g , fte );
17001702 if (err ) {
1701- up_write_ref_node (& g -> node );
1703+ up_write_ref_node (& g -> node , false );
17021704 if (err == - ENOSPC )
17031705 continue ;
17041706 kmem_cache_free (steering -> ftes_cache , fte );
17051707 return ERR_PTR (err );
17061708 }
17071709
17081710 nested_down_write_ref_node (& fte -> node , FS_LOCK_CHILD );
1709- up_write_ref_node (& g -> node );
1711+ up_write_ref_node (& g -> node , false );
17101712 rule = add_rule_fg (g , spec -> match_value ,
17111713 flow_act , dest , dest_num , fte );
1712- up_write_ref_node (& fte -> node );
1713- tree_put_node (& fte -> node );
1714+ up_write_ref_node (& fte -> node , false );
1715+ tree_put_node (& fte -> node , false );
17141716 return rule ;
17151717 }
17161718 rule = ERR_PTR (- ENOENT );
@@ -1752,7 +1754,7 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
17521754 err = build_match_list (& match_head , ft , spec );
17531755 if (err ) {
17541756 if (take_write )
1755- up_write_ref_node (& ft -> node );
1757+ up_write_ref_node (& ft -> node , false );
17561758 else
17571759 up_read_ref_node (& ft -> node );
17581760 return ERR_PTR (err );
@@ -1767,7 +1769,7 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
17671769 if (!IS_ERR (rule ) ||
17681770 (PTR_ERR (rule ) != - ENOENT && PTR_ERR (rule ) != - EAGAIN )) {
17691771 if (take_write )
1770- up_write_ref_node (& ft -> node );
1772+ up_write_ref_node (& ft -> node , false );
17711773 return rule ;
17721774 }
17731775
@@ -1783,12 +1785,12 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
17831785 g = alloc_auto_flow_group (ft , spec );
17841786 if (IS_ERR (g )) {
17851787 rule = ERR_CAST (g );
1786- up_write_ref_node (& ft -> node );
1788+ up_write_ref_node (& ft -> node , false );
17871789 return rule ;
17881790 }
17891791
17901792 nested_down_write_ref_node (& g -> node , FS_LOCK_PARENT );
1791- up_write_ref_node (& ft -> node );
1793+ up_write_ref_node (& ft -> node , false );
17921794
17931795 err = create_auto_flow_group (ft , g );
17941796 if (err )
@@ -1807,17 +1809,17 @@ _mlx5_add_flow_rules(struct mlx5_flow_table *ft,
18071809 }
18081810
18091811 nested_down_write_ref_node (& fte -> node , FS_LOCK_CHILD );
1810- up_write_ref_node (& g -> node );
1812+ up_write_ref_node (& g -> node , false );
18111813 rule = add_rule_fg (g , spec -> match_value , flow_act , dest ,
18121814 dest_num , fte );
1813- up_write_ref_node (& fte -> node );
1814- tree_put_node (& fte -> node );
1815- tree_put_node (& g -> node );
1815+ up_write_ref_node (& fte -> node , false );
1816+ tree_put_node (& fte -> node , false );
1817+ tree_put_node (& g -> node , false );
18161818 return rule ;
18171819
18181820err_release_fg :
1819- up_write_ref_node (& g -> node );
1820- tree_put_node (& g -> node );
1821+ up_write_ref_node (& g -> node , false );
1822+ tree_put_node (& g -> node , false );
18211823 return ERR_PTR (err );
18221824}
18231825
@@ -1883,7 +1885,7 @@ void mlx5_del_flow_rules(struct mlx5_flow_handle *handle)
18831885 int i ;
18841886
18851887 for (i = handle -> num_rules - 1 ; i >= 0 ; i -- )
1886- tree_remove_node (& handle -> rule [i ]-> node );
1888+ tree_remove_node (& handle -> rule [i ]-> node , false );
18871889 kfree (handle );
18881890}
18891891EXPORT_SYMBOL (mlx5_del_flow_rules );
@@ -1986,7 +1988,7 @@ int mlx5_destroy_flow_table(struct mlx5_flow_table *ft)
19861988 mutex_unlock (& root -> chain_lock );
19871989 return err ;
19881990 }
1989- if (tree_remove_node (& ft -> node ))
1991+ if (tree_remove_node (& ft -> node , false ))
19901992 mlx5_core_warn (get_dev (& ft -> node ), "Flow table %d wasn't destroyed, refcount > 1\n" ,
19911993 ft -> id );
19921994 mutex_unlock (& root -> chain_lock );
@@ -1997,7 +1999,7 @@ EXPORT_SYMBOL(mlx5_destroy_flow_table);
19971999
19982000void mlx5_destroy_flow_group (struct mlx5_flow_group * fg )
19992001{
2000- if (tree_remove_node (& fg -> node ))
2002+ if (tree_remove_node (& fg -> node , false ))
20012003 mlx5_core_warn (get_dev (& fg -> node ), "Flow group %d wasn't destroyed, refcount > 1\n" ,
20022004 fg -> id );
20032005}
@@ -2381,8 +2383,8 @@ static void clean_tree(struct fs_node *node)
23812383 tree_get_node (node );
23822384 list_for_each_entry_safe (iter , temp , & node -> children , list )
23832385 clean_tree (iter );
2384- tree_put_node (node );
2385- tree_remove_node (node );
2386+ tree_put_node (node , false );
2387+ tree_remove_node (node , false );
23862388 }
23872389}
23882390
0 commit comments