Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: remove RTNL use for /proc/sys/net/core/rps_default_mask

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>

authored by

Eric Dumazet and committed by
Jakub Kicinski
6058099d d8bf56a0

+28 -26
+12 -3
net/core/net-sysfs.c
··· 1210 1210 struct netdev_rx_queue *queue) 1211 1211 { 1212 1212 #if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL) 1213 - struct cpumask *rps_default_mask = READ_ONCE(dev_net(dev)->core.rps_default_mask); 1213 + struct cpumask *rps_default_mask; 1214 + int res = 0; 1214 1215 1216 + mutex_lock(&rps_default_mask_mutex); 1217 + 1218 + rps_default_mask = dev_net(dev)->core.rps_default_mask; 1215 1219 if (rps_default_mask && !cpumask_empty(rps_default_mask)) 1216 - return netdev_rx_queue_set_rps_mask(queue, rps_default_mask); 1217 - #endif 1220 + res = netdev_rx_queue_set_rps_mask(queue, rps_default_mask); 1221 + 1222 + mutex_unlock(&rps_default_mask_mutex); 1223 + 1224 + return res; 1225 + #else 1218 1226 return 0; 1227 + #endif 1219 1228 } 1220 1229 1221 1230 static int rx_queue_add_kobject(struct net_device *dev, int index)
+2
net/core/net-sysfs.h
··· 11 11 int netdev_change_owner(struct net_device *, const struct net *net_old, 12 12 const struct net *net_new); 13 13 14 + extern struct mutex rps_default_mask_mutex; 15 + 14 16 #endif
+14 -23
net/core/sysctl_net_core.c
··· 28 28 #include <net/rps.h> 29 29 30 30 #include "dev.h" 31 + #include "net-sysfs.h" 31 32 32 33 static int int_3600 = 3600; 33 34 static int min_sndbuf = SOCK_MIN_SNDBUF; ··· 97 96 98 97 #ifdef CONFIG_RPS 99 98 100 - static struct cpumask *rps_default_mask_cow_alloc(struct net *net) 101 - { 102 - struct cpumask *rps_default_mask; 103 - 104 - if (net->core.rps_default_mask) 105 - return net->core.rps_default_mask; 106 - 107 - rps_default_mask = kzalloc(cpumask_size(), GFP_KERNEL); 108 - if (!rps_default_mask) 109 - return NULL; 110 - 111 - /* pairs with READ_ONCE in rx_queue_default_mask() */ 112 - WRITE_ONCE(net->core.rps_default_mask, rps_default_mask); 113 - return rps_default_mask; 114 - } 99 + DEFINE_MUTEX(rps_default_mask_mutex); 115 100 116 101 static int rps_default_mask_sysctl(const struct ctl_table *table, int write, 117 102 void *buffer, size_t *lenp, loff_t *ppos) 118 103 { 119 104 struct net *net = (struct net *)table->data; 105 + struct cpumask *mask; 120 106 int err = 0; 121 107 122 - rtnl_lock(); 108 + mutex_lock(&rps_default_mask_mutex); 109 + mask = net->core.rps_default_mask; 123 110 if (write) { 124 - struct cpumask *rps_default_mask = rps_default_mask_cow_alloc(net); 125 - 111 + if (!mask) { 112 + mask = kzalloc(cpumask_size(), GFP_KERNEL); 113 + net->core.rps_default_mask = mask; 114 + } 126 115 err = -ENOMEM; 127 - if (!rps_default_mask) 116 + if (!mask) 128 117 goto done; 129 118 130 - err = cpumask_parse(buffer, rps_default_mask); 119 + err = cpumask_parse(buffer, mask); 131 120 if (err) 132 121 goto done; 133 122 134 - err = rps_cpumask_housekeeping(rps_default_mask); 123 + err = rps_cpumask_housekeeping(mask); 135 124 if (err) 136 125 goto done; 137 126 } else { 138 127 err = dump_cpumask(buffer, lenp, ppos, 139 - net->core.rps_default_mask ? : cpu_none_mask); 128 + mask ?: cpu_none_mask); 140 129 } 141 130 142 131 done: 143 - rtnl_unlock(); 132 + mutex_unlock(&rps_default_mask_mutex); 144 133 return err; 145 134 } 146 135