]> git.dujemihanovic.xyz Git - linux.git/commitdiff
net: no longer acquire RTNL in threaded_show()
authorEric Dumazet <edumazet@google.com>
Thu, 2 May 2024 17:39:26 +0000 (17:39 +0000)
committerJakub Kicinski <kuba@kernel.org>
Fri, 3 May 2024 22:14:01 +0000 (15:14 -0700)
dev->threaded can be read locklessly, if we add
corresponding READ_ONCE()/WRITE_ONCE() annotations.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20240502173926.2010646-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/netdevice.h
net/core/dev.c
net/core/net-sysfs.c

index 41853424b41d7a95e896e2f62318c161468c2437..2814a15eed73bfe27be6dc490b2e030158f86ead 100644 (file)
@@ -2370,8 +2370,8 @@ struct net_device {
        struct sfp_bus          *sfp_bus;
        struct lock_class_key   *qdisc_tx_busylock;
        bool                    proto_down;
+       bool                    threaded;
        unsigned                wol_enabled:1;
-       unsigned                threaded:1;
 
        struct list_head        net_notifier_list;
 
index e02d2363347e2e403ccb2a59d44d35cee9a1b367..d6b24749eb2e27ca87609e31b0434c6c09f0e8d8 100644 (file)
@@ -6531,7 +6531,7 @@ int dev_set_threaded(struct net_device *dev, bool threaded)
                }
        }
 
-       dev->threaded = threaded;
+       WRITE_ONCE(dev->threaded, threaded);
 
        /* Make sure kthread is created before THREADED bit
         * is set.
@@ -6622,7 +6622,7 @@ void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi,
         * threaded mode will not be enabled in napi_enable().
         */
        if (dev->threaded && napi_kthread_create(napi))
-               dev->threaded = 0;
+               dev->threaded = false;
        netif_napi_set_irq(napi, -1);
 }
 EXPORT_SYMBOL(netif_napi_add_weight);
index 1f7f09e567715f418bc163079d0dd19c51c3571c..4c27a360c2948e520b6cf06934553d82e250057d 100644 (file)
@@ -605,13 +605,13 @@ static ssize_t threaded_show(struct device *dev,
        struct net_device *netdev = to_net_dev(dev);
        ssize_t ret = -EINVAL;
 
-       if (!rtnl_trylock())
-               return restart_syscall();
+       rcu_read_lock();
 
        if (dev_isalive(netdev))
-               ret = sysfs_emit(buf, fmt_dec, netdev->threaded);
+               ret = sysfs_emit(buf, fmt_dec, READ_ONCE(netdev->threaded));
+
+       rcu_read_unlock();
 
-       rtnl_unlock();
        return ret;
 }