aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2025-01-14 20:55:27 +0000
committerJakub Kicinski <kuba@kernel.org>2025-01-15 19:17:03 -0800
commit0734d7c3d93cdcb8a56ce914d3c661300f24434d (patch)
tree80468bc3418393a591983bbe459a4c1d41f26474 /net/core/dev.c
parentnet: wwan: iosm: Fix hibernation by re-binding the driver around it (diff)
downloadlinux-0734d7c3d93cdcb8a56ce914d3c661300f24434d.tar.gz
linux-0734d7c3d93cdcb8a56ce914d3c661300f24434d.zip
net: expedite synchronize_net() for cleanup_net()
cleanup_net() is the single thread responsible for netns dismantles, and a serious bottleneck. Before we can get per-netns RTNL, make sure all synchronize_net() called from this thread are using rcu_synchronize_expedited(). v3: deal with CONFIG_NET_NS=n Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Jesse Brandeburg <jbrandeburg@cloudflare.com> Link: https://patch.msgid.link/20250114205531.967841-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 47e6b0f73cfc..115a7a0a1104 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -10099,6 +10099,15 @@ static void dev_index_release(struct net *net, int ifindex)
WARN_ON(xa_erase(&net->dev_by_index, ifindex));
}
+static bool from_cleanup_net(void)
+{
+#ifdef CONFIG_NET_NS
+ return current == cleanup_net_task;
+#else
+ return false;
+#endif
+}
+
/* Delayed registration/unregisteration */
LIST_HEAD(net_todo_list);
DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq);
@@ -11474,7 +11483,7 @@ EXPORT_SYMBOL_GPL(alloc_netdev_dummy);
void synchronize_net(void)
{
might_sleep();
- if (rtnl_is_locked())
+ if (from_cleanup_net() || rtnl_is_locked())
synchronize_rcu_expedited();
else
synchronize_rcu();