diff mbox series

[net-next] netpoll: remove netpoll_srcu

Message ID 20240905084909.2082486-1-edumazet@google.com (mailing list archive)
State Accepted
Commit 9a95eedc81deb86af1ac56f2c2bfe8306b27b82a
Delegated to: Netdev Maintainers
Headers show
Series [net-next] netpoll: remove netpoll_srcu | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 16 this patch: 16
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 5 of 5 maintainers
netdev/build_clang success Errors and warnings before: 16 this patch: 16
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 17 this patch: 17
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 43 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-09-06--21-00 (tests: 721)

Commit Message

Eric Dumazet Sept. 5, 2024, 8:49 a.m. UTC
netpoll_srcu is currently used from netpoll_poll_disable() and
__netpoll_cleanup()

Both functions run under RTNL, using netpoll_srcu adds confusion
and no additional protection.

Moreover the synchronize_srcu() call in __netpoll_cleanup() is
performed before clearing np->dev->npinfo, which violates RCU rules.

After this patch, netpoll_poll_disable() and netpoll_poll_enable()
simply use rtnl_dereference().

This saves a big chunk of memory (more than 192KB on platforms
with 512 cpus)

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Breno Leitao <leitao@debian.org>
---
 net/core/netpoll.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

Comments

Breno Leitao Sept. 5, 2024, 9:27 a.m. UTC | #1
Hello Eric,

On Thu, Sep 05, 2024 at 08:49:09AM +0000, Eric Dumazet wrote:
> netpoll_srcu is currently used from netpoll_poll_disable() and
> __netpoll_cleanup()
> 
> Both functions run under RTNL, using netpoll_srcu adds confusion
> and no additional protection.

Thanks for fixing it. I have never understood that SRCU in netpoll.

Reading this code now again, I have the impression that netpoll_srcu was
created to be able to dereference ->npinfo using an RCU primitive.

> Moreover the synchronize_srcu() call in __netpoll_cleanup() is
> performed before clearing np->dev->npinfo, which violates RCU rules.

I think the goal was to make sure that all the readers are not in the
critical section anymore, and wait for them. But it is unclear why it is
mixing srcu_read_lock() and rcu_read_lock() together.

Anyway, thanks for solving this.

> After this patch, netpoll_poll_disable() and netpoll_poll_enable()
> simply use rtnl_dereference().
> 
> This saves a big chunk of memory (more than 192KB on platforms
> with 512 cpus)
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Breno Leitao <leitao@debian.org>

Reviewed-by: Breno Leitao <leitao@debian.org>

I've double checked that netpoll_poll_disable() and
netpoll_poll_enable() is always called with rtnl held, so, the change is
safe.
patchwork-bot+netdevbpf@kernel.org Sept. 7, 2024, 1:30 a.m. UTC | #2
Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu,  5 Sep 2024 08:49:09 +0000 you wrote:
> netpoll_srcu is currently used from netpoll_poll_disable() and
> __netpoll_cleanup()
> 
> Both functions run under RTNL, using netpoll_srcu adds confusion
> and no additional protection.
> 
> Moreover the synchronize_srcu() call in __netpoll_cleanup() is
> performed before clearing np->dev->npinfo, which violates RCU rules.
> 
> [...]

Here is the summary with links:
  - [net-next] netpoll: remove netpoll_srcu
    https://git.kernel.org/netdev/net-next/c/9a95eedc81de

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index e0720ee6fa6206c44f996065f11261012da0fb6f..ca52cbe0f63cf6ae394da3cf1ed4cc7cd8a7254e 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -48,8 +48,6 @@ 
 
 static struct sk_buff_head skb_pool;
 
-DEFINE_STATIC_SRCU(netpoll_srcu);
-
 #define USEC_PER_POLL	50
 
 #define MAX_SKB_SIZE							\
@@ -220,23 +218,20 @@  EXPORT_SYMBOL(netpoll_poll_dev);
 void netpoll_poll_disable(struct net_device *dev)
 {
 	struct netpoll_info *ni;
-	int idx;
+
 	might_sleep();
-	idx = srcu_read_lock(&netpoll_srcu);
-	ni = srcu_dereference(dev->npinfo, &netpoll_srcu);
+	ni = rtnl_dereference(dev->npinfo);
 	if (ni)
 		down(&ni->dev_lock);
-	srcu_read_unlock(&netpoll_srcu, idx);
 }
 
 void netpoll_poll_enable(struct net_device *dev)
 {
 	struct netpoll_info *ni;
-	rcu_read_lock();
-	ni = rcu_dereference(dev->npinfo);
+
+	ni = rtnl_dereference(dev->npinfo);
 	if (ni)
 		up(&ni->dev_lock);
-	rcu_read_unlock();
 }
 
 static void refill_skbs(void)
@@ -829,8 +824,6 @@  void __netpoll_cleanup(struct netpoll *np)
 	if (!npinfo)
 		return;
 
-	synchronize_srcu(&netpoll_srcu);
-
 	if (refcount_dec_and_test(&npinfo->refcnt)) {
 		const struct net_device_ops *ops;