netpoll: remove netpoll_srcu
authorEric Dumazet <edumazet@google.com>
Thu, 5 Sep 2024 08:49:09 +0000 (08:49 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sat, 7 Sep 2024 01:24:59 +0000 (18:24 -0700)
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>
net/core/netpoll.c

index e0720ee..ca52cbe 100644 (file)
@@ -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;