]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: remove RTNL use for /proc/sys/net/core/rps_default_mask
authorEric Dumazet <edumazet@google.com>
Wed, 2 Jul 2025 06:15:58 +0000 (06:15 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 8 Jul 2025 01:42:12 +0000 (18:42 -0700)
Use a dedicated mutex instead.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250702061558.1585870-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/net-sysfs.c
net/core/net-sysfs.h
net/core/sysctl_net_core.c

index c9b96938639999ddc1fe52560e0ba2c4f1adff1f..8f897e2c8b4fe125a941f869709458830310169d 100644 (file)
@@ -1210,12 +1210,21 @@ static int rx_queue_default_mask(struct net_device *dev,
                                 struct netdev_rx_queue *queue)
 {
 #if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL)
-       struct cpumask *rps_default_mask = READ_ONCE(dev_net(dev)->core.rps_default_mask);
+       struct cpumask *rps_default_mask;
+       int res = 0;
 
+       mutex_lock(&rps_default_mask_mutex);
+
+       rps_default_mask = dev_net(dev)->core.rps_default_mask;
        if (rps_default_mask && !cpumask_empty(rps_default_mask))
-               return netdev_rx_queue_set_rps_mask(queue, rps_default_mask);
-#endif
+               res = netdev_rx_queue_set_rps_mask(queue, rps_default_mask);
+
+       mutex_unlock(&rps_default_mask_mutex);
+
+       return res;
+#else
        return 0;
+#endif
 }
 
 static int rx_queue_add_kobject(struct net_device *dev, int index)
index 8a5b04c2699aaee13ccc3a5b1543eecd0fc10d29..e938f25e8e86f9dfd8f710a08922c4cabf662c2e 100644 (file)
@@ -11,4 +11,6 @@ int netdev_queue_update_kobjects(struct net_device *net,
 int netdev_change_owner(struct net_device *, const struct net *net_old,
                        const struct net *net_new);
 
+extern struct mutex rps_default_mask_mutex;
+
 #endif
index 5dbb2c6f371defbf79d4581f9b6c1c3fb13fa9d9..8cf04b57ade1e0bf61ad4ac219ab4eccf638658a 100644 (file)
@@ -28,6 +28,7 @@
 #include <net/rps.h>
 
 #include "dev.h"
+#include "net-sysfs.h"
 
 static int int_3600 = 3600;
 static int min_sndbuf = SOCK_MIN_SNDBUF;
@@ -96,50 +97,40 @@ free_buf:
 
 #ifdef CONFIG_RPS
 
-static struct cpumask *rps_default_mask_cow_alloc(struct net *net)
-{
-       struct cpumask *rps_default_mask;
-
-       if (net->core.rps_default_mask)
-               return net->core.rps_default_mask;
-
-       rps_default_mask = kzalloc(cpumask_size(), GFP_KERNEL);
-       if (!rps_default_mask)
-               return NULL;
-
-       /* pairs with READ_ONCE in rx_queue_default_mask() */
-       WRITE_ONCE(net->core.rps_default_mask, rps_default_mask);
-       return rps_default_mask;
-}
+DEFINE_MUTEX(rps_default_mask_mutex);
 
 static int rps_default_mask_sysctl(const struct ctl_table *table, int write,
                                   void *buffer, size_t *lenp, loff_t *ppos)
 {
        struct net *net = (struct net *)table->data;
+       struct cpumask *mask;
        int err = 0;
 
-       rtnl_lock();
+       mutex_lock(&rps_default_mask_mutex);
+       mask = net->core.rps_default_mask;
        if (write) {
-               struct cpumask *rps_default_mask = rps_default_mask_cow_alloc(net);
-
+               if (!mask) {
+                       mask = kzalloc(cpumask_size(), GFP_KERNEL);
+                       net->core.rps_default_mask = mask;
+               }
                err = -ENOMEM;
-               if (!rps_default_mask)
+               if (!mask)
                        goto done;
 
-               err = cpumask_parse(buffer, rps_default_mask);
+               err = cpumask_parse(buffer, mask);
                if (err)
                        goto done;
 
-               err = rps_cpumask_housekeeping(rps_default_mask);
+               err = rps_cpumask_housekeeping(mask);
                if (err)
                        goto done;
        } else {
                err = dump_cpumask(buffer, lenp, ppos,
-                                  net->core.rps_default_mask ? : cpu_none_mask);
+                                  mask ?: cpu_none_mask);
        }
 
 done:
-       rtnl_unlock();
+       mutex_unlock(&rps_default_mask_mutex);
        return err;
 }