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

net: introduce default_rps_mask netns attribute

If RPS is enabled, this allows configuring a default rps
mask, which is effective since receive queue creation time.

A default RPS mask allows the system admin to ensure proper
isolation, avoiding races at network namespace or device
creation time.

The default RPS mask is initially empty, and can be
modified via a newly added sysctl entry.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Paolo Abeni and committed by
Jakub Kicinski
605cfa1b 370ca718

+50 -1
+6
Documentation/admin-guide/sysctl/net.rst
··· 215 215 216 216 The maximum receive socket buffer size in bytes. 217 217 218 + rps_default_mask 219 + ---------------- 220 + 221 + The default RPS CPU mask used on newly created network devices. An empty 222 + mask means RPS disabled by default. 223 + 218 224 tstamp_allow_data 219 225 ----------------- 220 226 Allow processes to receive tx timestamps looped together with the original
+1
include/linux/netdevice.h
··· 223 223 #include <linux/static_key.h> 224 224 extern struct static_key_false rps_needed; 225 225 extern struct static_key_false rfs_needed; 226 + extern struct cpumask rps_default_mask; 226 227 #endif 227 228 228 229 struct neighbour;
+7
net/core/net-sysfs.c
··· 1083 1083 goto err; 1084 1084 } 1085 1085 1086 + #if IS_ENABLED(CONFIG_RPS) && IS_ENABLED(CONFIG_SYSCTL) 1087 + if (!cpumask_empty(&rps_default_mask)) { 1088 + error = netdev_rx_queue_set_rps_mask(queue, &rps_default_mask); 1089 + if (error) 1090 + goto err; 1091 + } 1092 + #endif 1086 1093 kobject_uevent(kobj, KOBJ_ADD); 1087 1094 1088 1095 return error;
+36 -1
net/core/sysctl_net_core.c
··· 16 16 #include <linux/vmalloc.h> 17 17 #include <linux/init.h> 18 18 #include <linux/slab.h> 19 + #include <linux/sched/isolation.h> 19 20 20 21 #include <net/ip.h> 21 22 #include <net/sock.h> ··· 46 45 int sysctl_devconf_inherit_init_net __read_mostly; 47 46 EXPORT_SYMBOL(sysctl_devconf_inherit_init_net); 48 47 49 - #if IS_ENABLED(CONFIG_NET_FLOW_LIMIT) 48 + #if IS_ENABLED(CONFIG_NET_FLOW_LIMIT) || IS_ENABLED(CONFIG_RPS) 50 49 static void dump_cpumask(void *buffer, size_t *lenp, loff_t *ppos, 51 50 struct cpumask *mask) 52 51 { ··· 74 73 #endif 75 74 76 75 #ifdef CONFIG_RPS 76 + struct cpumask rps_default_mask; 77 + 78 + static int rps_default_mask_sysctl(struct ctl_table *table, int write, 79 + void *buffer, size_t *lenp, loff_t *ppos) 80 + { 81 + int err = 0; 82 + 83 + rtnl_lock(); 84 + if (write) { 85 + err = cpumask_parse(buffer, &rps_default_mask); 86 + if (err) 87 + goto done; 88 + 89 + err = rps_cpumask_housekeeping(&rps_default_mask); 90 + if (err) 91 + goto done; 92 + } else { 93 + dump_cpumask(buffer, lenp, ppos, &rps_default_mask); 94 + } 95 + 96 + done: 97 + rtnl_unlock(); 98 + return err; 99 + } 100 + 77 101 static int rps_sock_flow_sysctl(struct ctl_table *table, int write, 78 102 void *buffer, size_t *lenp, loff_t *ppos) 79 103 { ··· 508 482 .mode = 0644, 509 483 .proc_handler = rps_sock_flow_sysctl 510 484 }, 485 + { 486 + .procname = "rps_default_mask", 487 + .mode = 0644, 488 + .proc_handler = rps_default_mask_sysctl 489 + }, 511 490 #endif 512 491 #ifdef CONFIG_NET_FLOW_LIMIT 513 492 { ··· 716 685 717 686 static __init int sysctl_core_init(void) 718 687 { 688 + #if IS_ENABLED(CONFIG_RPS) 689 + cpumask_copy(&rps_default_mask, cpu_none_mask); 690 + #endif 691 + 719 692 register_net_sysctl(&init_net, "net/core", net_core_table); 720 693 return register_pernet_subsys(&sysctl_core_ops); 721 694 }