]> www.infradead.org Git - users/willy/linux.git/commitdiff
net: When removing nexthops, don't call synchronize_net if it is not necessary
authorChristoph Paasch <cpaasch@openai.com>
Sat, 16 Aug 2025 23:12:49 +0000 (16:12 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 20 Aug 2025 00:50:33 +0000 (17:50 -0700)
When removing a nexthop, commit
90f33bffa382 ("nexthops: don't modify published nexthop groups") added a
call to synchronize_rcu() (later changed to _net()) to make sure
everyone sees the new nexthop-group before the rtnl-lock is released.

When one wants to delete a large number of groups and nexthops, it is
fastest to first flush the groups (ip nexthop flush groups) and then
flush the nexthops themselves (ip -6 nexthop flush). As that way the
groups don't need to be rebalanced.

However, `ip -6 nexthop flush` will still take a long time if there is
a very large number of nexthops because of the call to
synchronize_net(). Now, if there are no more groups, there is no point
in calling synchronize_net(). So, let's skip that entirely by checking
if nh->grp_list is empty.

This gives us a nice speedup:

BEFORE:
=======

$ time sudo ip -6 nexthop flush
Dump was interrupted and may be inconsistent.
Flushed 2097152 nexthops

real 1m45.345s
user 0m0.001s
sys 0m0.005s

$ time sudo ip -6 nexthop flush
Dump was interrupted and may be inconsistent.
Flushed 4194304 nexthops

real 3m10.430s
user 0m0.002s
sys 0m0.004s

AFTER:
======

$ time sudo ip -6 nexthop flush
Dump was interrupted and may be inconsistent.
Flushed 2097152 nexthops

real 0m17.545s
user 0m0.003s
sys 0m0.003s

$ time sudo ip -6 nexthop flush
Dump was interrupted and may be inconsistent.
Flushed 4194304 nexthops

real 0m35.823s
user 0m0.002s
sys 0m0.004s

Signed-off-by: Christoph Paasch <cpaasch@openai.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250816-nexthop_dump-v2-2-491da3462118@openai.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/nexthop.c

index 509004bfd08ec43de44c7ce4a540c983d0e70201..0a20625f5ffb471052d92b48802076b8295dd703 100644 (file)
@@ -2087,6 +2087,12 @@ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh,
 {
        struct nh_grp_entry *nhge, *tmp;
 
+       /* If there is nothing to do, let's avoid the costly call to
+        * synchronize_net()
+        */
+       if (list_empty(&nh->grp_list))
+               return;
+
        list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list)
                remove_nh_grp_entry(net, nhge, nlinfo);