[SRU][N:linux-bluefield][PATCH v1 1/3] UBUNTU: SAUCE: ipv4: Provide a FIB flushing signal from nexthop removal functions
Stav Aviram
saviram at nvidia.com
Thu May 7 11:20:16 UTC 2026
From: Cosmin Ratiu <cratiu at nvidia.com>
BugLink: https://bugs.launchpad.net/bugs/2151772
Plumb a bool value throughout the various nexthop removal functions,
determined in the innermost __remove_nexthop_fib() (which still does the
FIB flushing) and propagated up all callers.
The next patch will make use of this signal to optimize the removal of
multiple nexthops by moving the FIB flushing up the call hierarchy.
Signed-off-by: Cosmin Ratiu <cratiu at nvidia.com>
Signed-off-by: Stav Aviram <saviram at nvidia.com>
---
net/ipv4/nexthop.c | 48 +++++++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 99385fe34a1e..d746dcc45c93 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -20,7 +20,7 @@
#define NH_RES_DEFAULT_IDLE_TIMER (120 * HZ)
#define NH_RES_DEFAULT_UNBALANCED_TIMER 0 /* No forced rebalancing. */
-static void remove_nexthop(struct net *net, struct nexthop *nh,
+static bool remove_nexthop(struct net *net, struct nexthop *nh,
struct nl_info *nlinfo);
#define NH_DEV_HASHBITS 8
@@ -1754,7 +1754,7 @@ static void nh_hthr_group_rebalance(struct nh_group *nhg)
}
}
-static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
+static bool remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
struct nl_info *nlinfo)
{
struct nh_grp_entry *nhges, *new_nhges;
@@ -1770,10 +1770,8 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
newg = nhg->spare;
/* last entry, keep it visible and remove the parent */
- if (nhg->num_nh == 1) {
- remove_nexthop(net, nhp, nlinfo);
- return;
- }
+ if (nhg->num_nh == 1)
+ return remove_nexthop(net, nhp, nlinfo);
newg->has_v4 = false;
newg->is_multipath = nhg->is_multipath;
@@ -1828,24 +1826,29 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
if (nlinfo)
nexthop_notify(RTM_NEWNEXTHOP, nhp, nlinfo);
+
+ return false;
}
-static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh,
+static bool remove_nexthop_from_groups(struct net *net, struct nexthop *nh,
struct nl_info *nlinfo)
{
struct nh_grp_entry *nhge, *tmp;
+ bool need_flush = false;
/* If there is nothing to do, let's avoid the costly call to
* synchronize_net()
*/
if (list_empty(&nh->grp_list))
- return;
+ return false;
list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list)
- remove_nh_grp_entry(net, nhge, nlinfo);
+ need_flush |= remove_nh_grp_entry(net, nhge, nlinfo);
/* make sure all see the newly published array before releasing rtnl */
synchronize_net();
+
+ return need_flush;
}
static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo)
@@ -1870,17 +1873,15 @@ static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo)
}
/* not called for nexthop replace */
-static void __remove_nexthop_fib(struct net *net, struct nexthop *nh)
+static bool __remove_nexthop_fib(struct net *net, struct nexthop *nh)
{
+ bool need_flush = !list_empty(&nh->fi_list);
struct fib6_info *f6i, *tmp;
- bool do_flush = false;
struct fib_info *fi;
- list_for_each_entry(fi, &nh->fi_list, nh_list) {
+ list_for_each_entry(fi, &nh->fi_list, nh_list)
fi->fib_flags |= RTNH_F_DEAD;
- do_flush = true;
- }
- if (do_flush)
+ if (need_flush)
fib_flush(net);
/* ip6_del_rt removes the entry from this list hence the _safe */
@@ -1890,12 +1891,13 @@ static void __remove_nexthop_fib(struct net *net, struct nexthop *nh)
ipv6_stub->ip6_del_rt(net, f6i,
!READ_ONCE(net->ipv4.sysctl_nexthop_compat_mode));
}
+ return need_flush;
}
-static void __remove_nexthop(struct net *net, struct nexthop *nh,
+static bool __remove_nexthop(struct net *net, struct nexthop *nh,
struct nl_info *nlinfo)
{
- __remove_nexthop_fib(net, nh);
+ bool need_flush = __remove_nexthop_fib(net, nh);
if (nh->is_group) {
remove_nexthop_group(nh, nlinfo);
@@ -1906,13 +1908,17 @@ static void __remove_nexthop(struct net *net, struct nexthop *nh,
if (nhi->fib_nhc.nhc_dev)
hlist_del(&nhi->dev_hash);
- remove_nexthop_from_groups(net, nh, nlinfo);
+ need_flush |= remove_nexthop_from_groups(net, nh, nlinfo);
}
+
+ return need_flush;
}
-static void remove_nexthop(struct net *net, struct nexthop *nh,
+static bool remove_nexthop(struct net *net, struct nexthop *nh,
struct nl_info *nlinfo)
{
+ bool need_flush;
+
call_nexthop_notifiers(net, NEXTHOP_EVENT_DEL, nh, NULL);
/* remove from the tree */
@@ -1921,10 +1927,12 @@ static void remove_nexthop(struct net *net, struct nexthop *nh,
if (nlinfo)
nexthop_notify(RTM_DELNEXTHOP, nh, nlinfo);
- __remove_nexthop(net, nh, nlinfo);
+ need_flush = __remove_nexthop(net, nh, nlinfo);
nh_base_seq_inc(net);
nexthop_put(nh);
+
+ return need_flush;
}
/* if any FIB entries reference this nexthop, any dst entries
--
2.38.1
More information about the kernel-team
mailing list