rtnetlink: Call unregister_netdevice_many() only once in rtnl_link_unregister().

When rtnl_link_unregister() is called during module unload, it
calls __rtnl_kill_links() for every netns.

__rtnl_kill_links() collects all devices of the unloaded module
and passes them to unregister_netdevice_many().

Let's move unregister_netdevice_many() to rtnl_link_unregister()
to unregister all devices across netns in a single batch.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260703001009.1572444-3-kuniyu@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Kuniyuki Iwashima
2026-07-03 00:09:13 +00:00
committed by Paolo Abeni
parent 5ecbbb179e
commit 49c26d4bf1

View File

@@ -637,16 +637,15 @@ int rtnl_link_register(struct rtnl_link_ops *ops)
}
EXPORT_SYMBOL_GPL(rtnl_link_register);
static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops,
struct list_head *dev_kill_list)
{
struct net_device *dev;
LIST_HEAD(list_kill);
for_each_netdev(net, dev) {
if (dev->rtnl_link_ops == ops)
ops->dellink(dev, &list_kill);
ops->dellink(dev, dev_kill_list);
}
unregister_netdevice_many(&list_kill);
}
/* Return with the rtnl_lock held when there are no network
@@ -677,6 +676,7 @@ static void rtnl_lock_unregistering_all(void)
*/
void rtnl_link_unregister(struct rtnl_link_ops *ops)
{
LIST_HEAD(dev_kill_list);
struct net *net;
mutex_lock(&link_ops_mutex);
@@ -691,7 +691,9 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops)
rtnl_lock_unregistering_all();
for_each_net(net)
__rtnl_kill_links(net, ops);
__rtnl_kill_links(net, ops, &dev_kill_list);
unregister_netdevice_many(&dev_kill_list);
rtnl_unlock();
up_write(&pernet_ops_rwsem);