[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250108162255.1306392-4-edumazet@google.com>
Date: Wed, 8 Jan 2025 16:22:54 +0000
From: Eric Dumazet <edumazet@...gle.com>
To: "David S . Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>
Cc: netdev@...r.kernel.org, Simon Horman <horms@...nel.org>, eric.dumazet@...il.com,
Eric Dumazet <edumazet@...gle.com>
Subject: [PATCH v2 net-next 3/4] net: no longer hold RTNL while calling flush_all_backlogs()
flush_all_backlogs() is called from unregister_netdevice_many_notify()
as part of netdevice dismantles.
This is currently called under RTNL, and can last up to 20ms on busy hosts.
There is no reason to hold RTNL at this stage, if our caller
is cleanup_net() : netns are no more visible, devices
are in NETREG_UNREGISTERING state and no other thread
could mess our state while RTNL is temporarily released.
Signed-off-by: Eric Dumazet <edumazet@...gle.com>
---
net/core/dev.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 8ff288cf25dceb5856496388f83f409fcb6f8e5d..86fa9ae29d31a25dca8204c75fd39974ef84707d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -11436,6 +11436,18 @@ static bool from_cleanup_net(void)
return current == cleanup_net_task;
}
+static void rtnl_drop_if_cleanup_net(void)
+{
+ if (from_cleanup_net())
+ __rtnl_unlock();
+}
+
+static void rtnl_acquire_if_cleanup_net(void)
+{
+ if (from_cleanup_net())
+ rtnl_lock();
+}
+
/**
* synchronize_net - Synchronize with packet receive processing
*
@@ -11548,8 +11560,10 @@ void unregister_netdevice_many_notify(struct list_head *head,
unlist_netdevice(dev);
WRITE_ONCE(dev->reg_state, NETREG_UNREGISTERING);
}
- flush_all_backlogs();
+ rtnl_drop_if_cleanup_net();
+ flush_all_backlogs();
+ rtnl_acquire_if_cleanup_net();
synchronize_net();
list_for_each_entry(dev, head, unreg_list) {
--
2.47.1.613.gc27f4b7a9f-goog
Powered by blists - more mailing lists