summaryrefslogtreecommitdiff
path: root/net/bridge/br.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2022-02-17 23:01:50 -0800
committerDavid S. Miller <davem@davemloft.net>2022-02-19 16:20:12 +0000
commit36a29fb6b22d7fd74c43c83e33d1a077092df4aa (patch)
tree30ac37c79f34b9ebb70ea06ad8f0cc5e0a4f8627 /net/bridge/br.c
parenta7cc3464e6673fe39cc23fdf538fe2ac9b1ec5e7 (diff)
bridge: switch br_net_exit to batch mode
cleanup_net() is competing with other rtnl users. Instead of calling br_net_exit() for each netns, call br_net_exit_batch() once. This gives cleanup_net() ability to group more devices and call unregister_netdevice_many() only once for all bridge devices. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Roopa Prabhu <roopa@nvidia.com> Cc: Nikolay Aleksandrov <razor@blackwall.org> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br.c')
-rw-r--r--net/bridge/br.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 1fac72cc617f..b1dea3febeea 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -342,23 +342,26 @@ void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on)
clear_bit(opt, &br->options);
}
-static void __net_exit br_net_exit(struct net *net)
+static void __net_exit br_net_exit_batch(struct list_head *net_list)
{
struct net_device *dev;
+ struct net *net;
LIST_HEAD(list);
rtnl_lock();
- for_each_netdev(net, dev)
- if (netif_is_bridge_master(dev))
- br_dev_delete(dev, &list);
+
+ list_for_each_entry(net, net_list, exit_list)
+ for_each_netdev(net, dev)
+ if (netif_is_bridge_master(dev))
+ br_dev_delete(dev, &list);
unregister_netdevice_many(&list);
- rtnl_unlock();
+ rtnl_unlock();
}
static struct pernet_operations br_net_ops = {
- .exit = br_net_exit,
+ .exit_batch = br_net_exit_batch,
};
static const struct stp_proto br_stp_proto = {