From: Ondrej Lichtner olichtne@redhat.com
This commit implements a new PerfTestTweakMixin called once per perf_test method that handles configuration of ipfragmentation thresholds in case a udp flow is being measured.
The mixin includes detection for which IP version the flow will use and configures the ip fragmentation specifically for that version.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com --- .../CommonPerfTestTweakMixin.py | 14 +- .../UdpFragmentationPerfTestMixin.py | 126 ++++++++++++++++++ lnst/Recipes/ENRT/PerfTestMixins/__init__.py | 1 + 3 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 lnst/Recipes/ENRT/PerfTestMixins/UdpFragmentationPerfTestMixin.py
diff --git a/lnst/Recipes/ENRT/PerfTestMixins/CommonPerfTestTweakMixin.py b/lnst/Recipes/ENRT/PerfTestMixins/CommonPerfTestTweakMixin.py index ebe5965..7b77234 100644 --- a/lnst/Recipes/ENRT/PerfTestMixins/CommonPerfTestTweakMixin.py +++ b/lnst/Recipes/ENRT/PerfTestMixins/CommonPerfTestTweakMixin.py @@ -1,7 +1,13 @@ from lnst.Recipes.ENRT.PerfTestMixins import ( - SctpFirewallPerfTestMixin, - DropCachesPerfTestMixin, - ) + SctpFirewallPerfTestMixin, + UdpFragmentationPerfTestMixin, + DropCachesPerfTestMixin, +)
-class CommonPerfTestTweakMixin(SctpFirewallPerfTestMixin, DropCachesPerfTestMixin): + +class CommonPerfTestTweakMixin( + SctpFirewallPerfTestMixin, + UdpFragmentationPerfTestMixin, + DropCachesPerfTestMixin, +): pass diff --git a/lnst/Recipes/ENRT/PerfTestMixins/UdpFragmentationPerfTestMixin.py b/lnst/Recipes/ENRT/PerfTestMixins/UdpFragmentationPerfTestMixin.py new file mode 100644 index 0000000..7f60c6c --- /dev/null +++ b/lnst/Recipes/ENRT/PerfTestMixins/UdpFragmentationPerfTestMixin.py @@ -0,0 +1,126 @@ +from lnst.Common.LnstError import LnstError +from lnst.Common.Parameters import IntParam +from lnst.Common.IpAddress import ipaddress, AF_INET, AF_INET6 +from lnst.Controller.RecipeResults import ResultLevel +from lnst.RecipeCommon.Perf.PerfTestMixins import BasePerfTestTweakMixin +from lnst.Recipes.ENRT.PerfTestMixins.Utils import ( + get_flow_measurements_from_config, +) + + +class UdpFragmentationPerfTestMixin(BasePerfTestTweakMixin): + udp_fragmentation_threshold = IntParam(default=104857600) + + def apply_perf_test_tweak(self, perf_config): + super().apply_perf_test_tweak(perf_config) + + flow_measurements = get_flow_measurements_from_config(perf_config) + flow = flow_measurements[0].conf[0] + tweak_config = perf_config.perf_test_tweak_config + if flow.type == "udp_stream": + tweak_config["udp_fragmentation"] = {} + for host in self.matched: + self._config_ip_fragmentation(tweak_config, host, flow) + + def _config_ip_fragmentation(self, config, host, flow): + ip_version = self._flow_ip_version(flow) + + if ip_version == AF_INET: + orig_value = host.run( + "cat /proc/sys/net/ipv4/ipfrag_high_thresh", + job_level=ResultLevel.DEBUG, + ) + host.run( + "echo {} > /proc/sys/net/ipv4/ipfrag_high_thresh".format( + self.params.udp_fragmentation_threshold + ), + job_level=ResultLevel.NORMAL, + ) + host.run( + "echo 1 > /proc/sys/net/ipv4/ipfrag_time", + job_level=ResultLevel.NORMAL, + ) + elif ip_version == AF_INET6: + orig_value = host.run( + "cat /proc/sys/net/ipv6/ip6frag_high_thresh", + job_level=ResultLevel.DEBUG, + ) + host.run( + "echo {} > /proc/sys/net/ipv6/ip6frag_high_thresh".format( + self.params.udp_fragmentation_threshold + ), + job_level=ResultLevel.NORMAL, + ) + host.run( + "echo 1 > /proc/sys/net/ipv4/ipfrag_time", + job_level=ResultLevel.NORMAL, + ) + + config["udp_fragmentation"][host] = { + "ip_version": ip_version, + "original": orig_value.stdout.strip(), + "current": self.params.udp_fragmentation_threshold, + } + + def remove_perf_test_tweak(self, perf_config): + tweak_config = perf_config.perf_test_tweak_config + if "udp_fragmentation" in tweak_config: + for host, host_cfg in tweak_config["udp_fragmentation"].items(): + self._deconfig_ip_fragmentation(host_cfg, host) + + del tweak_config["udp_fragmentation"] + + super().remove_perf_test_tweak(perf_config) + + def _deconfig_ip_fragmentation(self, config, host): + ip_version = config["ip_version"] + + if ip_version == AF_INET: + host.run( + "echo {} > /proc/sys/net/ipv4/ipfrag_high_thresh".format( + config["original"] + ), + job_level=ResultLevel.NORMAL, + ) + host.run( + "echo 30 > /proc/sys/net/ipv4/ipfrag_time", + job_level=ResultLevel.NORMAL, + ) + elif ip_version == AF_INET6: + host.run( + "echo {} > /proc/sys/net/ipv6/ip6frag_high_thresh".format( + config["original"] + ), + job_level=ResultLevel.NORMAL, + ) + host.run( + "echo 30 > /proc/sys/net/ipv6/ip6frag_time", + job_level=ResultLevel.NORMAL, + ) + else: + raise LnstError("Unknown ip version: {}".format(ip_version)) + + def generate_perf_test_tweak_description(self, perf_config): + description = super().generate_perf_test_tweak_description(perf_config) + tweak_config = perf_config.perf_test_tweak_config + if "udp_fragmentation" in tweak_config: + for host, host_cfg in tweak_config["udp_fragmentation"].items(): + description.append( + "Host {hid} configured ipfrag_high_thresh={value}".format( + hid=host.hostid, value=host_cfg["current"] + ) + ) + description.append( + "Host {hid} configured ipfrag_time=1".format( + hid=host.hostid + ) + ) + else: + description.append( + "skipped configuration of fragmentation thresholds" + ) + + return description + + def _flow_ip_version(self, flow): + return ipaddress(flow.generator_bind).family diff --git a/lnst/Recipes/ENRT/PerfTestMixins/__init__.py b/lnst/Recipes/ENRT/PerfTestMixins/__init__.py index 93709ad..3f012da 100644 --- a/lnst/Recipes/ENRT/PerfTestMixins/__init__.py +++ b/lnst/Recipes/ENRT/PerfTestMixins/__init__.py @@ -1,3 +1,4 @@ from lnst.Recipes.ENRT.PerfTestMixins.SctpFirewallPerfTestMixin import SctpFirewallPerfTestMixin +from lnst.Recipes.ENRT.PerfTestMixins.UdpFragmentationPerfTestMixin import UdpFragmentationPerfTestMixin from lnst.Recipes.ENRT.PerfTestMixins.DropCachesPerfTestMixin import DropCachesPerfTestMixin from lnst.Recipes.ENRT.PerfTestMixins.CommonPerfTestTweakMixin import CommonPerfTestTweakMixin