@@ -1578,6 +1578,33 @@ static u64 matched_fgs_get_version(struct list_head *match_head)
1578
1578
return version ;
1579
1579
}
1580
1580
1581
+ static struct fs_fte *
1582
+ lookup_fte_locked (struct mlx5_flow_group * g ,
1583
+ u32 * match_value ,
1584
+ bool take_write )
1585
+ {
1586
+ struct fs_fte * fte_tmp ;
1587
+
1588
+ if (take_write )
1589
+ nested_down_write_ref_node (& g -> node , FS_LOCK_PARENT );
1590
+ else
1591
+ nested_down_read_ref_node (& g -> node , FS_LOCK_PARENT );
1592
+ fte_tmp = rhashtable_lookup_fast (& g -> ftes_hash , match_value ,
1593
+ rhash_fte );
1594
+ if (!fte_tmp || !tree_get_node (& fte_tmp -> node )) {
1595
+ fte_tmp = NULL ;
1596
+ goto out ;
1597
+ }
1598
+
1599
+ nested_down_write_ref_node (& fte_tmp -> node , FS_LOCK_CHILD );
1600
+ out :
1601
+ if (take_write )
1602
+ up_write_ref_node (& g -> node );
1603
+ else
1604
+ up_read_ref_node (& g -> node );
1605
+ return fte_tmp ;
1606
+ }
1607
+
1581
1608
static struct mlx5_flow_handle *
1582
1609
try_add_to_existing_fg (struct mlx5_flow_table * ft ,
1583
1610
struct list_head * match_head ,
@@ -1600,31 +1627,16 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
1600
1627
if (IS_ERR (fte ))
1601
1628
return ERR_PTR (- ENOMEM );
1602
1629
1603
- list_for_each_entry (iter , match_head , list ) {
1604
- nested_down_read_ref_node (& iter -> g -> node , FS_LOCK_PARENT );
1605
- }
1606
-
1607
1630
search_again_locked :
1608
1631
version = matched_fgs_get_version (match_head );
1609
1632
/* Try to find a fg that already contains a matching fte */
1610
1633
list_for_each_entry (iter , match_head , list ) {
1611
1634
struct fs_fte * fte_tmp ;
1612
1635
1613
1636
g = iter -> g ;
1614
- fte_tmp = rhashtable_lookup_fast (& g -> ftes_hash , spec -> match_value ,
1615
- rhash_fte );
1616
- if (!fte_tmp || !tree_get_node (& fte_tmp -> node ))
1637
+ fte_tmp = lookup_fte_locked (g , spec -> match_value , take_write );
1638
+ if (!fte_tmp )
1617
1639
continue ;
1618
-
1619
- nested_down_write_ref_node (& fte_tmp -> node , FS_LOCK_CHILD );
1620
- if (!take_write ) {
1621
- list_for_each_entry (iter , match_head , list )
1622
- up_read_ref_node (& iter -> g -> node );
1623
- } else {
1624
- list_for_each_entry (iter , match_head , list )
1625
- up_write_ref_node (& iter -> g -> node );
1626
- }
1627
-
1628
1640
rule = add_rule_fg (g , spec -> match_value ,
1629
1641
flow_act , dest , dest_num , fte_tmp );
1630
1642
up_write_ref_node (& fte_tmp -> node );
@@ -1633,19 +1645,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
1633
1645
return rule ;
1634
1646
}
1635
1647
1636
- /* No group with matching fte found. Try to add a new fte to any
1637
- * matching fg.
1638
- */
1639
-
1640
- if (!take_write ) {
1641
- list_for_each_entry (iter , match_head , list )
1642
- up_read_ref_node (& iter -> g -> node );
1643
- list_for_each_entry (iter , match_head , list )
1644
- nested_down_write_ref_node (& iter -> g -> node ,
1645
- FS_LOCK_PARENT );
1646
- take_write = true;
1647
- }
1648
-
1649
1648
/* Check the ft version, for case that new flow group
1650
1649
* was added while the fgs weren't locked
1651
1650
*/
@@ -1657,27 +1656,30 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
1657
1656
/* Check the fgs version, for case the new FTE with the
1658
1657
* same values was added while the fgs weren't locked
1659
1658
*/
1660
- if (version != matched_fgs_get_version (match_head ))
1659
+ if (version != matched_fgs_get_version (match_head )) {
1660
+ take_write = true;
1661
1661
goto search_again_locked ;
1662
+ }
1662
1663
1663
1664
list_for_each_entry (iter , match_head , list ) {
1664
1665
g = iter -> g ;
1665
1666
1666
1667
if (!g -> node .active )
1667
1668
continue ;
1669
+
1670
+ nested_down_write_ref_node (& g -> node , FS_LOCK_PARENT );
1671
+
1668
1672
err = insert_fte (g , fte );
1669
1673
if (err ) {
1674
+ up_write_ref_node (& g -> node );
1670
1675
if (err == - ENOSPC )
1671
1676
continue ;
1672
- list_for_each_entry (iter , match_head , list )
1673
- up_write_ref_node (& iter -> g -> node );
1674
1677
kmem_cache_free (steering -> ftes_cache , fte );
1675
1678
return ERR_PTR (err );
1676
1679
}
1677
1680
1678
1681
nested_down_write_ref_node (& fte -> node , FS_LOCK_CHILD );
1679
- list_for_each_entry (iter , match_head , list )
1680
- up_write_ref_node (& iter -> g -> node );
1682
+ up_write_ref_node (& g -> node );
1681
1683
rule = add_rule_fg (g , spec -> match_value ,
1682
1684
flow_act , dest , dest_num , fte );
1683
1685
up_write_ref_node (& fte -> node );
@@ -1686,8 +1688,6 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
1686
1688
}
1687
1689
rule = ERR_PTR (- ENOENT );
1688
1690
out :
1689
- list_for_each_entry (iter , match_head , list )
1690
- up_write_ref_node (& iter -> g -> node );
1691
1691
kmem_cache_free (steering -> ftes_cache , fte );
1692
1692
return rule ;
1693
1693
}
0 commit comments