ppp: Split ppp_exit_net() to ->exit_rtnl().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Fri, 18 Apr 2025 00:32:34 +0000 (17:32 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 23 Apr 2025 02:07:41 +0000 (19:07 -0700)
ppp_exit_net() unregisters devices related to the netns under
RTNL and destroys lists and IDR.

Let's use ->exit_rtnl() for the device unregistration part to
save RTNL dances for each netns.

Note that we delegate the for_each_netdev_safe() part to
default_device_exit_batch() and replace unregister_netdevice_queue()
with ppp_nl_dellink() to align with bond, geneve, gtp, and pfcp.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250418003259.48017-4-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ppp/ppp_generic.c

index 53463767cc43eb18fddaebe43aa88686db639ecf..def84e87e05b2e9daa7a5717d20b58854d74dbf1 100644 (file)
@@ -1131,6 +1131,8 @@ static const struct file_operations ppp_device_fops = {
        .llseek         = noop_llseek,
 };
 
+static void ppp_nl_dellink(struct net_device *dev, struct list_head *head);
+
 static __net_init int ppp_init_net(struct net *net)
 {
        struct ppp_net *pn = net_generic(net, ppp_net_id);
@@ -1146,28 +1148,20 @@ static __net_init int ppp_init_net(struct net *net)
        return 0;
 }
 
-static __net_exit void ppp_exit_net(struct net *net)
+static __net_exit void ppp_exit_rtnl_net(struct net *net,
+                                        struct list_head *dev_to_kill)
 {
        struct ppp_net *pn = net_generic(net, ppp_net_id);
-       struct net_device *dev;
-       struct net_device *aux;
        struct ppp *ppp;
-       LIST_HEAD(list);
        int id;
 
-       rtnl_lock();
-       for_each_netdev_safe(net, dev, aux) {
-               if (dev->netdev_ops == &ppp_netdev_ops)
-                       unregister_netdevice_queue(dev, &list);
-       }
-
        idr_for_each_entry(&pn->units_idr, ppp, id)
-               /* Skip devices already unregistered by previous loop */
-               if (!net_eq(dev_net(ppp->dev), net))
-                       unregister_netdevice_queue(ppp->dev, &list);
+               ppp_nl_dellink(ppp->dev, dev_to_kill);
+}
 
-       unregister_netdevice_many(&list);
-       rtnl_unlock();
+static __net_exit void ppp_exit_net(struct net *net)
+{
+       struct ppp_net *pn = net_generic(net, ppp_net_id);
 
        mutex_destroy(&pn->all_ppp_mutex);
        idr_destroy(&pn->units_idr);
@@ -1177,6 +1171,7 @@ static __net_exit void ppp_exit_net(struct net *net)
 
 static struct pernet_operations ppp_net_ops = {
        .init = ppp_init_net,
+       .exit_rtnl = ppp_exit_rtnl_net,
        .exit = ppp_exit_net,
        .id   = &ppp_net_id,
        .size = sizeof(struct ppp_net),