net: introduce rps_default_mask
Subsystems (4)
Paolo Abeni
maintainerv2 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.
These series try to address the above, introducing a new sysctl knob: rps_default_mask. The new sysctl entry allows configuring a systemwide 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.
v1 -> v2:
- fix sparse warning in patch 2/3
Paolo Abeni (3):
net/sysctl: factor-out netdev_rx_queue_set_rps_mask() helper net/core: 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/net-sysfs.c | 73 +++++++++++-------- net/core/sysctl_net_core.c | 58 +++++++++++++++ tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/config | 3 + .../testing/selftests/net/rps_default_mask.sh | 57 +++++++++++++++ 7 files changed, 169 insertions(+), 30 deletions(-) create mode 100755 tools/testing/selftests/net/rps_default_mask.sh
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 1/3 net/sysctl: factor-out netdev_rx_queue_set_rps_mask() helper
Will simplify the following patch. No functional change intended.
--- net/core/net-sysfs.c | 66 ++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 30 deletions(-)
net/core/net-sysfs.c +36 -30
@@ -737,42 +737,18 @@ static ssize_t show_rps_map(struct netdev_rx_queue *queue, char *buf)return len <PAGE_SIZE ? len : -EINVAL ; } -static ssize_t store_rps_map (struct netdev_rx_queue *queue, -const char *buf,size_t len) +static int netdev_rx_queue_set_rps_mask (struct netdev_rx_queue *queue, +cpumask_var_t mask) { -struct rps_map *old_map, *map; -cpumask_var_t mask; -int err, cpu, i, hk_flags;static DEFINE_MUTEX (rps_map_mutex); - -if (!capable (CAP_NET_ADMIN )) -return -EPERM ; - -if (!alloc_cpumask_var (&mask,GFP_KERNEL )) -return -ENOMEM ; - - err =bitmap_parse (buf, len,cpumask_bits (mask), nr_cpumask_bits); -if (err) { -free_cpumask_var (mask); -return err; - } - -if (!cpumask_empty (mask)) { - hk_flags =HK_FLAG_DOMAIN |HK_FLAG_WQ ; -cpumask_and (mask, mask,housekeeping_cpumask (hk_flags)); -if (cpumask_empty (mask)) { -free_cpumask_var (mask); -return -EINVAL ; - } - } +struct rps_map *old_map, *map; +int cpu, i; map = kzalloc(max_t(unsigned int,RPS_MAP_SIZE (cpumask_weight (mask)),L1_CACHE_BYTES ),GFP_KERNEL ); -if (!map) { -free_cpumask_var (mask); +if (!map)return -ENOMEM ; - } i =0 ;for_each_cpu_and (cpu, mask, cpu_online_mask)
@@ -799,9 +775,39 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue,if (old_map)kfree_rcu (old_map, rcu); +return 0 ; +} + +static ssize_t store_rps_map (struct netdev_rx_queue *queue, +const char *buf,size_t len) +{ +cpumask_var_t mask; +int err, hk_flags; + +if (!capable (CAP_NET_ADMIN )) +return -EPERM ; + +if (!alloc_cpumask_var (&mask,GFP_KERNEL )) +return -ENOMEM ; + + err =bitmap_parse (buf, len,cpumask_bits (mask), nr_cpumask_bits); +if (err) + goto out; +if (!cpumask_empty (mask)) { + hk_flags =HK_FLAG_DOMAIN |HK_FLAG_WQ ; +cpumask_and (mask, mask,housekeeping_cpumask (hk_flags)); +if (cpumask_empty (mask)) { + err = -EINVAL ; + goto out; + } + } + + err =netdev_rx_queue_set_rps_mask (queue, mask); + +out:free_cpumask_var (mask); -return len; +return err ? : len; } static ssize_t show_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 2/3 net/core: 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.
v1 -> v2:
- declare rps_default_mask in netdevice.h to avoid a sparse warning - Jakub
--- Documentation/admin-guide/sysctl/net.rst | 6 +++ include/linux/netdevice.h | 1 + net/core/net-sysfs.c | 7 +++ net/core/sysctl_net_core.c | 58 ++++++++++++++++++++++++ 4 files changed, 72 insertions(+)
Documentation/admin-guide/sysctl/net.rst +6 -0
@@ -211,6 +211,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
@@ -200,6 +200,7 @@ struct net_device_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
@@ -983,6 +983,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 +58 -0
82 lines not on this page · raw message
Signature · 1 line
2.26.2
Paolo Abeni
maintainerPATCH v2 3/3 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
@@ -21,6 +21,7 @@ TEST_PROGS += rxtimestamp.sh TEST_PROGS += devlink_port_split.py TEST_PROGS += drop_monitor_tests.sh TEST_PROGS += vrf_route_leaking.sh +TEST_PROGS += rps_default_mask.sh TEST_PROGS_EXTENDED := in_netns.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
tools/testing/selftests/net/config +3 -0
@@ -34,3 +34,6 @@ CONFIG_TRACEPOINTS=y CONFIG_NET_DROP_MONITOR=m CONFIG_NETDEVSIM=m CONFIG_NET_FOU=m +CONFIG_RPS=y +CONFIG_SYSFS=y +CONFIG_PROC_SYSCTL=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.26.2
Jakub Kicinski
maintainerQuoted 10 lines · On Fri, 30 Oct 2020 12:16:00 +0100 Paolo Abeni 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.
Quoted 8 lines
These series try to address the above, introducing a new sysctl knob:
rps_default_mask. The new sysctl entry allows configuring a systemwide 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_maskbehavior.
RPS is disabled by default, the processing is going to happen wherever the IRQ is mapped, and one would hope that the IRQ is not mapped to the core where the critical processing runs.
Would you mind elaborating further on the use case?
Quoted 12 lines · Jakub Kicinski
Quoted 11 lines · On Fri, 30 Oct 2020 12:16:00 +0100 Paolo Abeni 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.
Quoted 6 lines
Quoted 6 lines
These series try to address the above, introducing a new sysctl knob:
rps_default_mask. The new sysctl entry allows configuring a systemwide RPS mask, to be enforced since receive queue creation time without any fourther per device configuration required.
The whole thing can be replaced with a user daemon scripts that monitors all newly created devices and assign to them whatever rps mask (call it default).
So why do we need this special logic in kernel ?
I am not sure about this, but if rps queues sysfs are available before the netdev is up, then you can also use udevd to assign the rps masks before such devices are even brought up, so you would avoid the race conditions that you described, which are not really clear to me to be honest.
Quoted 10 lines
Quoted 2 lines
Additionally, a simple self-test is introduced to check the
rps_default_maskbehavior.RPS is disabled by default, the processing is going to happen wherever
the IRQ is mapped, and one would hope that the IRQ is not mapped to the
core where the critical processing runs.Would you mind elaborating further on the use case?
Paolo Abeni
maintainerQuoted 25 lines · Jakub Kicinski
Quoted 10 lines · On Fri, 30 Oct 2020 12:16:00 +0100 Paolo Abeni 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.
Quoted 8 lines
These series try to address the above, introducing a new sysctl knob:
rps_default_mask. The new sysctl entry allows configuring a systemwide 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_maskbehavior.RPS is disabled by default, the processing is going to happen wherever the IRQ is mapped, and one would hope that the IRQ is not mapped to the core where the critical processing runs.
Would you mind elaborating further on the use case?
Quoted 11 lines · Saeed Mahameed
The whole thing can be replaced with a user daemon scripts that monitors all newly created devices and assign to them whatever rps mask (call it default).
So why do we need this special logic in kernel ?
I am not sure about this, but if rps queues sysfs are available before the netdev is up, then you can also use udevd to assign the rps masks before such devices are even brought up, so you would avoid the race conditions that you described, which are not really clear to me to be honest.
Thank you for the feedback.
Please allow me to answer you both here, as your questions are related.
The relevant use case is an host running containers (with the related orchestration tools) in a RT environment. Virtual devices (veths, ovs ports, etc.) are created by the orchestration tools at run-time. Critical processes are allowed to send packets/generate outgoing network traffic - but any interrupt is moved away from the related cores, so that usual incoming network traffic processing does not happen there.
Still an xmit operation on a virtual devices may be transmitted via ovs or veth, with the relevant forwarding operation happening in a softirq on the same CPU originating the packet.
RPS is configured (even) on such virtual devices to move away the forwarding from the relevant CPUs.
As Saeed noted, such configuration could be possibly performed via some user-space daemon monitoring network devices and network namespaces creation. That will be anyway prone to some race: the orchestation tool may create and enable the netns and virtual devices before the daemon has properly set the RPS mask.
In the latter scenario some packet forwarding could still slip in the relevant CPU, causing measurable latency. In all non RT scenarios the above will be likely irrelevant, but in the RT context that is not acceptable - e.g. it causes in real environments latency above the defined limits, while the proposed patches avoid the issue.
Do you see any other simple way to avoid the above race?
Please let me know if the above answers your doubts,
Paolo
Jakub Kicinski
maintainerQuoted 71 lines · On Tue, 03 Nov 2020 16:22:07 +0100 Paolo Abeni wrote:
Quoted 25 lines · Jakub Kicinski
Quoted 10 lines · On Fri, 30 Oct 2020 12:16:00 +0100 Paolo Abeni 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.
Quoted 8 lines
These series try to address the above, introducing a new sysctl knob:
rps_default_mask. The new sysctl entry allows configuring a systemwide 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_maskbehavior.RPS is disabled by default, the processing is going to happen wherever the IRQ is mapped, and one would hope that the IRQ is not mapped to the core where the critical processing runs.
Would you mind elaborating further on the use case?
Quoted 11 lines · Saeed Mahameed
The whole thing can be replaced with a user daemon scripts that monitors all newly created devices and assign to them whatever rps mask (call it default).
So why do we need this special logic in kernel ?
I am not sure about this, but if rps queues sysfs are available before the netdev is up, then you can also use udevd to assign the rps masks before such devices are even brought up, so you would avoid the race conditions that you described, which are not really clear to me to be honest.
Thank you for the feedback.
Please allow me to answer you both here, as your questions are related.
The relevant use case is an host running containers (with the related orchestration tools) in a RT environment. Virtual devices (veths, ovs ports, etc.) are created by the orchestration tools at run-time. Critical processes are allowed to send packets/generate outgoing network traffic - but any interrupt is moved away from the related cores, so that usual incoming network traffic processing does not happen there.
Still an xmit operation on a virtual devices may be transmitted via ovs or veth, with the relevant forwarding operation happening in a softirq on the same CPU originating the packet.
RPS is configured (even) on such virtual devices to move away the forwarding from the relevant CPUs.
As Saeed noted, such configuration could be possibly performed via some user-space daemon monitoring network devices and network namespaces creation. That will be anyway prone to some race: the orchestation tool may create and enable the netns and virtual devices before the daemon has properly set the RPS mask.
In the latter scenario some packet forwarding could still slip in the relevant CPU, causing measurable latency. In all non RT scenarios the above will be likely irrelevant, but in the RT context that is not acceptable - e.g. it causes in real environments latency above the defined limits, while the proposed patches avoid the issue.
Quoted 3 lines
Do you see any other simple way to avoid the above race?
Please let me know if the above answers your doubts,
Thanks, that makes it clearer now.
Depending on how RT-aware your container management is it may or may not be the right place to configure this, as it creates the veth interface. Presumably it's the container management which does the placement of the tasks to cores, why is it not setting other attributes, like RPS?
Also I wonder if it would make sense to turn this knob into something more generic. When we arrive at the threaded NAPIs - could it make sense for the threads to inherit your mask as the CPUs they are allowed to run on?
Paolo Abeni
maintainerQuoted 30 lines · Jakub Kicinski
Quoted 29 lines · On Tue, 03 Nov 2020 16:22:07 +0100 Paolo Abeni wrote:
The relevant use case is an host running containers (with the related orchestration tools) in a RT environment. Virtual devices (veths, ovs ports, etc.) are created by the orchestration tools at run-time. Critical processes are allowed to send packets/generate outgoing network traffic - but any interrupt is moved away from the related cores, so that usual incoming network traffic processing does not happen there.
Still an xmit operation on a virtual devices may be transmitted via ovs or veth, with the relevant forwarding operation happening in a softirq on the same CPU originating the packet.
RPS is configured (even) on such virtual devices to move away the forwarding from the relevant CPUs.
As Saeed noted, such configuration could be possibly performed via some user-space daemon monitoring network devices and network namespaces creation. That will be anyway prone to some race: the orchestation tool may create and enable the netns and virtual devices before the daemon has properly set the RPS mask.
In the latter scenario some packet forwarding could still slip in the relevant CPU, causing measurable latency. In all non RT scenarios the above will be likely irrelevant, but in the RT context that is not acceptable - e.g. it causes in real environments latency above the defined limits, while the proposed patches avoid the issue.
Do you see any other simple way to avoid the above race?
Quoted 8 lines
Quoted 1 line
Please let me know if the above answers your doubts,
Thanks, that makes it clearer now.
Depending on how RT-aware your container management is it may or may not be the right place to configure this, as it creates the veth interface. Presumably it's the container management which does the placement of the tasks to cores, why is it not setting other attributes, like RPS?
The container orchestration is quite complex, and I'm unsure isolation and networking configuration are performed (or can be performed) by the same precess (without an heavy refactor).
On the flip hand, the global rps mask knob looked quite straightforward to me.
Possibly I can reduce the amount of new code introduced by this patchset removing some code duplication
between rps_default_mask_sysctl() and flow_limit_cpu_sysctl(). Would that make this change more acceptable? Or should I drop this altogether?
Quoted 4 lines
Also I wonder if it would make sense to turn this knob into something more generic. When we arrive at the threaded NAPIs - could it make sense for the threads to inherit your mask as the CPUs they are allowed to run on?
I personally *think* this would be fine - and good. But isn't a bit premature discussing the integration of 2 missing pieces ? :)
Thanks,
Paolo
Quoted 35 lines · Paolo Abeni
Quoted 34 lines · Jakub Kicinski
Quoted 27 lines · On Tue, 03 Nov 2020 16:22:07 +0100 Paolo Abeni wrote:
The relevant use case is an host running containers (with the related orchestration tools) in a RT environment. Virtual devices (veths, ovs ports, etc.) are created by the orchestration tools at run-time. Critical processes are allowed to send packets/generate outgoing network traffic - but any interrupt is moved away from the related cores, so that usual incoming network traffic processing does not happen there.
Still an xmit operation on a virtual devices may be transmitted via ovs or veth, with the relevant forwarding operation happening in a softirq on the same CPU originating the packet.
RPS is configured (even) on such virtual devices to move away the forwarding from the relevant CPUs.
As Saeed noted, such configuration could be possibly performed via some user-space daemon monitoring network devices and network namespaces creation. That will be anyway prone to some race: the orchestation tool may create and enable the netns and virtual devices before the daemon has properly set the RPS mask.
In the latter scenario some packet forwarding could still slip in the relevant CPU, causing measurable latency. In all non RT scenarios the above will be likely irrelevant, but in the RT context that is not acceptable - e.g. it causes in real environments latency above the defined limits, while the proposed patches avoid the issue.
Quoted 3 lines
Do you see any other simple way to avoid the above race?
Please let me know if the above answers your doubts,
Thanks, that makes it clearer now.
Quoted 8 lines
Quoted 4 lines
Depending on how RT-aware your container management is it may or may not be the right place to configure this, as it creates the veth interface. Presumably it's the container management which does the placement of the tasks to cores, why is it not setting other attributes, like RPS?
The container orchestration is quite complex, and I'm unsure isolation and networking configuration are performed (or can be performed) by the same precess (without an heavy refactor).
Also for the host side (no containers) the same issue will have to be handled for PCI hotplug for example. So this fix will have to be performed in every tool that decides to create a network device (while a kernel solution is global).
Quoted 14 lines
On the flip hand, the global rps mask knob looked quite straightforward to me.
Possibly I can reduce the amount of new code introduced by this patchset removing some code duplication
betweenrps_default_mask_sysctl()andflow_limit_cpu_sysctl(). Would that make this change more acceptable? Or should I drop this altogether?Quoted 4 lines
Also I wonder if it would make sense to turn this knob into something more generic. When we arrive at the threaded NAPIs - could it make sense for the threads to inherit your mask as the CPUs they are allowed to run on?
Quoted 6 lines
I personally *think* this would be fine - and good. But isn't a bit premature discussing the integration of 2 missing pieces ? :)
Thanks,
Paolo
About the potential race:
0) network device creation starts, inherits old default_rps_mask,
network device init sleeps
1) set default_rps_mask (new)
2) change all devices across all network namespaces (walk /sys)
3) network device init wakes up, new device shows up in /sys/ using old default_rps_mask
Why this can't happen?
Jakub Kicinski
maintainerQuoted 40 lines · On Wed, 04 Nov 2020 18:36:08 +0100 Paolo Abeni wrote:
Quoted 30 lines · Jakub Kicinski
Quoted 29 lines · On Tue, 03 Nov 2020 16:22:07 +0100 Paolo Abeni wrote:
The relevant use case is an host running containers (with the related orchestration tools) in a RT environment. Virtual devices (veths, ovs ports, etc.) are created by the orchestration tools at run-time. Critical processes are allowed to send packets/generate outgoing network traffic - but any interrupt is moved away from the related cores, so that usual incoming network traffic processing does not happen there.
Still an xmit operation on a virtual devices may be transmitted via ovs or veth, with the relevant forwarding operation happening in a softirq on the same CPU originating the packet.
RPS is configured (even) on such virtual devices to move away the forwarding from the relevant CPUs.
As Saeed noted, such configuration could be possibly performed via some user-space daemon monitoring network devices and network namespaces creation. That will be anyway prone to some race: the orchestation tool may create and enable the netns and virtual devices before the daemon has properly set the RPS mask.
In the latter scenario some packet forwarding could still slip in the relevant CPU, causing measurable latency. In all non RT scenarios the above will be likely irrelevant, but in the RT context that is not acceptable - e.g. it causes in real environments latency above the defined limits, while the proposed patches avoid the issue.
Do you see any other simple way to avoid the above race?
Quoted 8 lines
Quoted 1 line
Please let me know if the above answers your doubts,
Thanks, that makes it clearer now.
Depending on how RT-aware your container management is it may or may not be the right place to configure this, as it creates the veth interface. Presumably it's the container management which does the placement of the tasks to cores, why is it not setting other attributes, like RPS?
Quoted 6 lines
The container orchestration is quite complex, and I'm unsure isolation and networking configuration are performed (or can be performed) by the same precess (without an heavy refactor).
On the flip hand, the global rps mask knob looked quite straightforward to me.
I understand, but I can't shake the feeling this is a hack.
Whatever sets the CPU isolation should take care of the RPS settings.
Quoted 5 lines
Possibly I can reduce the amount of new code introduced by this patchset removing some code duplication
betweenrps_default_mask_sysctl()andflow_limit_cpu_sysctl(). Would that make this change more acceptable? Or should I drop this altogether?
I'm leaning towards drop altogether, unless you can get some support/review tags from other netdev developers. So far it appears we only got a down vote from Saeed.
Quoted 7 lines
Quoted 4 lines
Also I wonder if it would make sense to turn this knob into something more generic. When we arrive at the threaded NAPIs - could it make sense for the threads to inherit your mask as the CPUs they are allowed to run on?
I personally *think* this would be fine - and good. But isn't a bit premature discussing the integration of 2 missing pieces ? :)
Paolo Abeni
maintainerHi all,
Quoted 45 lines · Jakub Kicinski
Quoted 44 lines · On Wed, 04 Nov 2020 18:36:08 +0100 Paolo Abeni wrote:
Quoted 30 lines · Jakub Kicinski
Quoted 29 lines · On Tue, 03 Nov 2020 16:22:07 +0100 Paolo Abeni wrote:
The relevant use case is an host running containers (with the related orchestration tools) in a RT environment. Virtual devices (veths, ovs ports, etc.) are created by the orchestration tools at run-time. Critical processes are allowed to send packets/generate outgoing network traffic - but any interrupt is moved away from the related cores, so that usual incoming network traffic processing does not happen there.
Still an xmit operation on a virtual devices may be transmitted via ovs or veth, with the relevant forwarding operation happening in a softirq on the same CPU originating the packet.
RPS is configured (even) on such virtual devices to move away the forwarding from the relevant CPUs.
As Saeed noted, such configuration could be possibly performed via some user-space daemon monitoring network devices and network namespaces creation. That will be anyway prone to some race: the orchestation tool may create and enable the netns and virtual devices before the daemon has properly set the RPS mask.
In the latter scenario some packet forwarding could still slip in the relevant CPU, causing measurable latency. In all non RT scenarios the above will be likely irrelevant, but in the RT context that is not acceptable - e.g. it causes in real environments latency above the defined limits, while the proposed patches avoid the issue.
Do you see any other simple way to avoid the above race?
Quoted 8 lines
Quoted 1 line
Please let me know if the above answers your doubts,
Thanks, that makes it clearer now.
Depending on how RT-aware your container management is it may or may not be the right place to configure this, as it creates the veth interface. Presumably it's the container management which does the placement of the tasks to cores, why is it not setting other attributes, like RPS?
The container orchestration is quite complex, and I'm unsure isolation and networking configuration are performed (or can be performed) by the same precess (without an heavy refactor).
Quoted 6 lines
Quoted 2 lines
On the flip hand, the global rps mask knob looked quite straightforward to me.
I understand, but I can't shake the feeling this is a hack.
Whatever sets the CPU isolation should take care of the RPS settings.
Let me try for a moment to revive this old thread.
Tha series proposed a new sysctl know to implement a global/default rps mask applying to all the network devices as a way to simplify some RT setups. It has been rejected as the required task is doable in user- space.
Currently the orchestration infrastructure does that, setting the per device, per queue rps mask and CPU isolation.
The above leads to a side problem: when there are lot of netns/devices with several queues, even a reasonably optimized user-space solution takes a relevant amount of time to traverse the relevant sysfs dirs and do I/O on them. Overall the additional time required is very measurable, easily ranging in seconds.
The default_rps_mask would basically kill that overhead.
Is the above a suitable use case?
Thanks,
Paolo
Jakub Kicinski
maintainerQuoted 16 lines · On Mon, 30 Jan 2023 10:25:34 +0100 Paolo Abeni wrote:
Let me try for a moment to revive this old thread.
Tha series proposed a new sysctl know to implement a global/default rps mask applying to all the network devices as a way to simplify some RT setups. It has been rejected as the required task is doable in user- space.
Currently the orchestration infrastructure does that, setting the per device, per queue rps mask and CPU isolation.
The above leads to a side problem: when there are lot of netns/devices with several queues, even a reasonably optimized user-space solution takes a relevant amount of time to traverse the relevant sysfs dirs and do I/O on them. Overall the additional time required is very measurable, easily ranging in seconds.
Quoted 3 lines
The
default_rps_maskwould basically kill that overhead.Is the above a suitable use case?
Alright, thanks for trying the user space fix.