net: introduce rps_default_mask
Subsystems (4)
Paolo Abeni
maintainerv4 cover net: introduce rps_default_mask
Real-time setups try hard to ensure proper isolation between time critical applications and e.g. network processing performed by the network stack in softirq and RPS is used to move the softirq activity away from the isolated core.
If the network configuration is dynamic, with netns and devices routinely created at run-time, enforcing the correct RPS setting on each newly created device allowing to transient bad configuration became complex.
Additionally, when multi-queue devices are involved, configuring rps in user-space on each queue easily becomes very expensive, e.g. some setups use veths with per cpu queues.
These series try to address the above, introducing a new sysctl knob: rps_default_mask. The new sysctl entry allows configuring a netns-wide RPS mask, to be enforced since receive queue creation time without any fourther per device configuration required.
Additionally, a simple self-test is introduced to check the rps_default_mask behavior.
v3 -> v4:
- fix build warning
v2 -> v3:
- reduce code duplication
- rebased
Paolo Abeni (4):
net-sysctl: factor out cpumask parsing helper
net-sysctl: factor-out rpm mask manipulation helpers
net: introduce default_rps_mask netns attribute
self-tests: introduce self-tests for RPS default mask
Documentation/admin-guide/sysctl/net.rst | 6 ++ include/linux/netdevice.h | 1 + net/core/dev.h | 2 + net/core/net-sysfs.c | 79 +++++++++++------- net/core/sysctl_net_core.c | 81 ++++++++++++++----- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/config | 3 + .../testing/selftests/net/rps_default_mask.sh | 57 +++++++++++++ 8 files changed, 182 insertions(+), 48 deletions(-) create mode 100755 tools/testing/selftests/net/rps_default_mask.sh
Signature · 1 line
2.39.1
Paolo Abeni
maintainerPATCH v4 1/4 net-sysctl: factor out cpumask parsing helper
Will be used by the following patch to avoid code duplication. No functional changes intended.
The only difference is that now flow_limit_cpu_sysctl() will always compute the flow limit mask on each read operation, even when read() will not return any byte to user-space.
Note that the new helper is placed under a new #ifdef at the file start to better fit the usage in the later patch
---
v3 -> v4:
- fix warning reported by the kernel test robot
--- net/core/sysctl_net_core.c | 46 +++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-)
net/core/sysctl_net_core.c +28 -18
@@ -45,6 +45,33 @@ EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net);int sysctl_devconf_inherit_init_net__read_mostly ;EXPORT_SYMBOL (sysctl_devconf_inherit_init_net); +#if IS_ENABLED (CONFIG_NET_FLOW_LIMIT ) +static void dump_cpumask (void *buffer,size_t *lenp,loff_t *ppos, +struct cpumask *mask) +{ +char kbuf[128 ]; +int len; + +if (*ppos || !*lenp) { + *lenp =0 ; +return ; + } + + len =min (sizeof (kbuf) -1 , *lenp); + len =scnprintf (kbuf, len,"%*pb" ,cpumask_pr_args (mask)); +if (!len) { + *lenp =0 ; +return ; + } + +if (len < *lenp) + kbuf[len++] ='\n' ; +memcpy (buffer, kbuf, len); + *lenp = len; + *ppos += len; +} +#endif +#ifdef CONFIG_RPS static int rps_sock_flow_sysctl (struct ctl_table *table,int write,void *buffer,size_t *lenp,loff_t *ppos)
@@ -155,13 +182,6 @@ static int flow_limit_cpu_sysctl(struct ctl_table *table, int write, write_unlock:mutex_unlock (&flow_limit_update_mutex); }else { -char kbuf[128 ]; - -if (*ppos || !*lenp) { - *lenp =0 ; - goto done; - } -cpumask_clear (mask);rcu_read_lock ();for_each_possible_cpu (i) {
@@ -171,17 +191,7 @@ static int flow_limit_cpu_sysctl(struct ctl_table *table, int write, }rcu_read_unlock (); - len =min (sizeof (kbuf) -1 , *lenp); - len =scnprintf (kbuf, len,"%*pb" ,cpumask_pr_args (mask)); -if (!len) { - *lenp =0 ; - goto done; - } -if (len < *lenp) - kbuf[len++] ='\n' ; -memcpy (buffer, kbuf, len); - *lenp = len; - *ppos += len; +dump_cpumask (buffer, lenp, ppos, mask); } done:
Signature · 1 line
2.39.1
Re: [PATCH v4 net-next 1/4] net-sysctl: factor out cpumask parsing helper
Quoted 11 lines · Paolo Abeni
Will be used by the following patch to avoid code duplication. No functional changes intended.
The only difference is that now
flow_limit_cpu_sysctl()will always compute the flow limit mask on each read operation, even whenread()will not return any byte to user-space.Note that the new helper is placed under a new #ifdef at the file start to better fit the usage in the later patch
Signed-off-by Paolo Abeni <[email protected]>
Paolo Abeni
maintainerPATCH v4 2/4 net-sysctl: factor-out rpm mask manipulation helpers
In reply to Paolo AbeniWill simplify the following patch. No functional change intended.
---
v2 -> v3: factor out the new rps_cpumask_housekeeping() helper
--- net/core/dev.h | 2 ++ net/core/net-sysfs.c | 72 ++++++++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 30 deletions(-)
net/core/dev.h +2 -0
@@ -9,6 +9,7 @@ struct net_device;struct netdev_bpf ;struct netdev_phys_item_id ;struct netlink_ext_ack ; +struct cpumask ;/* Random bits of netdevice that don't need to be exposed */ #define FLOW_LIMIT_HISTORY (1 << 7)/* must be ^2 and !overflow buckets */
@@ -134,4 +135,5 @@ static inline void netif_set_gro_ipv4_max_size(struct net_device *dev, WRITE_ONCE(dev->gro_ipv4_max_size, size); } +int rps_cpumask_housekeeping (struct cpumask *mask);#endif
net/core/net-sysfs.c +42 -30
93 lines not on this page · raw message
Signature · 1 line
2.39.1
Re: [PATCH v4 net-next 2/4] net-sysctl: factor-out rpm mask manipulation helpers
Quoted 4 lines · Paolo Abeni
Will simplify the following patch. No functional change intended.
Signed-off-by Paolo Abeni <[email protected]>
Paolo Abeni
maintainerPATCH v4 3/4 net: introduce default_rps_mask netns attribute
In reply to Paolo AbeniIf 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.
---
v2 -> v3:
- avoid a bit of code duplication thanks to new helpers in patch 1/4 and 2/4
--- Documentation/admin-guide/sysctl/net.rst | 6 ++++ include/linux/netdevice.h | 1 + net/core/net-sysfs.c | 7 +++++ net/core/sysctl_net_core.c | 37 +++++++++++++++++++++++- 4 files changed, 50 insertions(+), 1 deletion(-)
Documentation/admin-guide/sysctl/net.rst +6 -0
@@ -215,6 +215,12 @@ rmem_max The maximum receive socket buffer size in bytes. +rps_default_mask +---------------- + +The default RPS CPU mask used on newly created network devices. An empty +mask means RPS disabled by default. + tstamp_allow_data ----------------- Allow processes to receive tx timestamps looped together with the original
include/linux/netdevice.h +1 -0
@@ -223,6 +223,7 @@ struct net_device_core_stats {#include <linux/static_key.h> extern struct static_key_false rps_needed;extern struct static_key_false rfs_needed; +extern struct cpumask rps_default_mask;#endif struct neighbour ;
net/core/net-sysfs.c +7 -0
@@ -1083,6 +1083,13 @@ static int rx_queue_add_kobject(struct net_device *dev, int index) goto err; } +#if IS_ENABLED (CONFIG_RPS ) &&IS_ENABLED (CONFIG_SYSCTL ) +if (!cpumask_empty (&rps_default_mask)) { + error =netdev_rx_queue_set_rps_mask (queue, &rps_default_mask); +if (error) + goto err; + } +#endif kobject_uevent (kobj,KOBJ_ADD );return error;
net/core/sysctl_net_core.c +36 -1
@@ -16,6 +16,7 @@#include <linux/vmalloc.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/sched/isolation.h> #include <net/ip.h> #include <net/sock.h>
@@ -45,7 +46,7 @@ EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net);int sysctl_devconf_inherit_init_net__read_mostly ;EXPORT_SYMBOL (sysctl_devconf_inherit_init_net); -#if IS_ENABLED (CONFIG_NET_FLOW_LIMIT ) +#if IS_ENABLED (CONFIG_NET_FLOW_LIMIT ) ||IS_ENABLED (CONFIG_RPS )static void dump_cpumask (void *buffer,size_t *lenp,loff_t *ppos,struct cpumask *mask) {
@@ -73,6 +74,31 @@ static void dump_cpumask(void *buffer, size_t *lenp, loff_t *ppos,#endif #ifdef CONFIG_RPS +struct cpumask rps_default_mask; + +static int rps_default_mask_sysctl (struct ctl_table *table,int write, +void *buffer,size_t *lenp,loff_t *ppos) +{ +int err =0 ; + +rtnl_lock (); +if (write) { + err =cpumask_parse (buffer, &rps_default_mask); +if (err) + goto done; + + err =rps_cpumask_housekeeping (&rps_default_mask); +if (err) + goto done; + }else { +dump_cpumask (buffer, lenp, ppos, &rps_default_mask); + } + +done: +rtnl_unlock (); +return err; +} +static int rps_sock_flow_sysctl (struct ctl_table *table,int write,void *buffer,size_t *lenp,loff_t *ppos) {
@@ -482,6 +508,11 @@ static struct ctl_table net_core_table[] = { .mode = 0644, .proc_handler = rps_sock_flow_sysctl }, + { + .procname = "rps_default_mask", + .mode = 0644, + .proc_handler = rps_default_mask_sysctl + },#endif #ifdef CONFIG_NET_FLOW_LIMIT {
@@ -685,6 +716,10 @@ static __net_initdata struct pernet_operations sysctl_core_ops = {static __init int sysctl_core_init (void ) { +#if IS_ENABLED (CONFIG_RPS ) +cpumask_copy (&rps_default_mask, cpu_none_mask); +#endif +register_net_sysctl (&init_net,"net/core" , net_core_table);return register_pernet_subsys (&sysctl_core_ops); }
Signature · 1 line
2.39.1
Re: [PATCH v4 net-next 3/4] net: introduce default_rps_mask netns attribute
Quoted 11 lines · Paolo Abeni
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 <[email protected]>
Paolo Abeni
maintainerPATCH v4 4/4 self-tests: introduce self-tests for RPS default mask
In reply to Paolo AbeniEnsure that RPS default mask changes take place on all newly created netns/devices and don't affect existing ones.
--- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/config | 3 + .../testing/selftests/net/rps_default_mask.sh | 57 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100755 tools/testing/selftests/net/rps_default_mask.sh
tools/testing/selftests/net/Makefile +1 -0
@@ -46,6 +46,7 @@ TEST_PROGS += stress_reuseport_listen.sh TEST_PROGS += l2_tos_ttl_inherit.sh TEST_PROGS += bind_bhash.sh TEST_PROGS += ip_local_port_range.sh +TEST_PROGS += rps_default_mask.sh TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh TEST_PROGS_EXTENDED += toeplitz_client.sh toeplitz.sh TEST_GEN_FILES = socket nettest
tools/testing/selftests/net/config +3 -0
@@ -3,6 +3,9 @@ CONFIG_NET_NS=y CONFIG_BPF_SYSCALL=y CONFIG_TEST_BPF=m CONFIG_NUMA=y +CONFIG_RPS=y +CONFIG_SYSFS=y +CONFIG_PROC_SYSCTL=y CONFIG_NET_VRF=y CONFIG_NET_L3_MASTER_DEV=y CONFIG_IPV6=y
tools/testing/selftests/net/rps_default_mask.sh new file +57 -0
57 lines not on this page · raw message
Signature · 1 line
2.39.1
Re: [PATCH v4 net-next 4/4] self-tests: introduce self-tests for RPS default mask
Quoted 5 lines · Paolo Abeni
Ensure that RPS default mask changes take place on all newly created netns/devices and don't affect existing ones.
Signed-off-by Paolo Abeni <[email protected]>
Quoted 15 lines · Paolo Abeni
Real-time setups try hard to ensure proper isolation between time critical applications and e.g. network processing performed by the network stack in softirq and RPS is used to move the softirq activity away from the isolated core.
If the network configuration is dynamic, with netns and devices routinely created at run-time, enforcing the correct RPS setting on each newly created device allowing to transient bad configuration became complex.
Additionally, when multi-queue devices are involved, configuring rps in user-space on each queue easily becomes very expensive, e.g. some setups use veths with per cpu queues.
Quoted 5 lines
These series try to address the above, introducing a new sysctl knob:
rps_default_mask. The new sysctl entry allows configuring a netns-wide RPS mask, to be enforced since receive queue creation time without any fourther per device configuration required.
This series was applied to netdev/net-next.git (master) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net-next.git (master) by Jakub Kicinski <[email protected]>:
Quoted 11 lines · On Tue, 7 Feb 2023 19:44:54 +0100 you wrote:
Real-time setups try hard to ensure proper isolation between time critical applications and e.g. network processing performed by the network stack in softirq and RPS is used to move the softirq activity away from the isolated core.
If the network configuration is dynamic, with netns and devices routinely created at run-time, enforcing the correct RPS setting on each newly created device allowing to transient bad configuration became complex.
[...]
Here is the summary with links:
- [v4,net-next,1/4] net-sysctl: factor out cpumask parsing helper
https://git.kernel.org/netdev/net-next/c/135746c61fa6 - [v4,net-next,2/4] net-sysctl: factor-out rpm mask manipulation helpers https://git.kernel.org/netdev/net-next/c/370ca718fd5e - [v4,net-next,3/4] net: introduce default_rps_mask netns attribute https://git.kernel.org/netdev/net-next/c/605cfa1b1090 - [v4,net-next,4/4] self-tests: introduce self-tests for RPS default mask https://git.kernel.org/netdev/net-next/c/c12e0d5f267d
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html