6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit 9a95eedc81deb86af1ac56f2c2bfe8306b27b82a ]
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 Stable-dep-of: 49c8d2c1f94c ("net: netpoll: fix incorrect refcount handling causing incorrect cleanup") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/core/netpoll.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
--- 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,24 +218,21 @@ 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); } EXPORT_SYMBOL(netpoll_poll_disable);
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(); } EXPORT_SYMBOL(netpoll_poll_enable);
@@ -843,8 +838,6 @@ void __netpoll_cleanup(struct netpoll *n if (!npinfo) return;
- synchronize_srcu(&netpoll_srcu); - if (refcount_dec_and_test(&npinfo->refcnt)) { const struct net_device_ops *ops;