gtp: use exit_batch_rtnl() method
authorEric Dumazet <edumazet@google.com>
Tue, 6 Feb 2024 14:43:03 +0000 (14:43 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 8 Feb 2024 02:55:11 +0000 (18:55 -0800)
exit_batch_rtnl() is called while RTNL is held,
and devices to be unregistered can be queued in the dev_kill_list.

This saves one rtnl_lock()/rtnl_unlock() pair per netns
and one unregister_netdevice_many() call per netns.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Antoine Tenart <atenart@kernel.org>
Link: https://lore.kernel.org/r/20240206144313.2050392-8-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/gtp.c

index b1919278e931f4e9fb6b2d2ec2feb2193b2cda61..62c601d9f7528d456dc6695814bf01a4d756d2da 100644 (file)
@@ -1876,23 +1876,23 @@ static int __net_init gtp_net_init(struct net *net)
        return 0;
 }
 
-static void __net_exit gtp_net_exit(struct net *net)
+static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
+                                              struct list_head *dev_to_kill)
 {
-       struct gtp_net *gn = net_generic(net, gtp_net_id);
-       struct gtp_dev *gtp;
-       LIST_HEAD(list);
+       struct net *net;
 
-       rtnl_lock();
-       list_for_each_entry(gtp, &gn->gtp_dev_list, list)
-               gtp_dellink(gtp->dev, &list);
+       list_for_each_entry(net, net_list, exit_list) {
+               struct gtp_net *gn = net_generic(net, gtp_net_id);
+               struct gtp_dev *gtp;
 
-       unregister_netdevice_many(&list);
-       rtnl_unlock();
+               list_for_each_entry(gtp, &gn->gtp_dev_list, list)
+                       gtp_dellink(gtp->dev, dev_to_kill);
+       }
 }
 
 static struct pernet_operations gtp_net_ops = {
        .init   = gtp_net_init,
-       .exit   = gtp_net_exit,
+       .exit_batch_rtnl = gtp_net_exit_batch_rtnl,
        .id     = &gtp_net_id,
        .size   = sizeof(struct gtp_net),
 };