diff options
author | Eric Dumazet <edumazet@google.com> | 2024-09-05 08:49:09 +0000 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2024-09-06 18:24:59 -0700 |
commit | 9a95eedc81deb86af1ac56f2c2bfe8306b27b82a (patch) | |
tree | c12e40e9ded07ea80218166dbc7820eeec345764 /net/core/netpoll.c | |
parent | c6a1739778949d5fdfbb1443b41acf5c43879283 (diff) | |
download | linux-9a95eedc81deb86af1ac56f2c2bfe8306b27b82a.tar.gz linux-9a95eedc81deb86af1ac56f2c2bfe8306b27b82a.tar.bz2 linux-9a95eedc81deb86af1ac56f2c2bfe8306b27b82a.zip |
netpoll: remove netpoll_srcu
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>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20240905084909.2082486-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r-- | net/core/netpoll.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index e0720ee6fa62..ca52cbe0f63c 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; |