From 81ccc81dde69acb26c422bda99284b5d243bf0e1 Mon Sep 17 00:00:00 2001 From: Karol Latecki Date: Thu, 4 Feb 2021 12:49:51 +0100 Subject: [PATCH] scripts/nvmf_perf: add configure_sysctl method Tune sysctl parameters for TCP testing. Restore previous settings after tests have finished. For ADQ-enabled tests also set proper value for busy_read option. Commit includes a fix to initiator exec_cmd() method to allow using command parameters which contains whitespace, otherwise it's not possible to set some of sysctl params. Signed-off-by: Karol Latecki Change-Id: I3376b69b8d7c0d8a282765db4fe55824f55f9e05 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6265 Tested-by: SPDK CI Jenkins Reviewed-by: Michal Berger Reviewed-by: Jim Harris Reviewed-by: Tomasz Zawadzki Reviewed-by: Maciej Wawryk Reviewed-by: John Kariuki --- scripts/perf/nvmf/run_nvmf.py | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/scripts/perf/nvmf/run_nvmf.py b/scripts/perf/nvmf/run_nvmf.py index 641391425..8c8674ce9 100755 --- a/scripts/perf/nvmf/run_nvmf.py +++ b/scripts/perf/nvmf/run_nvmf.py @@ -32,6 +32,7 @@ class Server: self.local_nic_info = [] self._nics_json_obj = {} self.svc_restore_dict = {} + self.sysctl_restore_dict = {} self.enable_adq = False self.adq_priority = None @@ -81,6 +82,7 @@ class Server: def configure_system(self): self.configure_services() + self.configure_sysctl() def configure_adq(self): self.adq_load_modules() @@ -154,12 +156,43 @@ class Server: self.log_print("Disabling %s. It will be restored after the test has finished." % service) self.exec_cmd(["sudo", "systemctl", "stop", service]) + def configure_sysctl(self): + self.log_print("Tuning sysctl settings...") + + busy_read = 50000 + if self.enable_adq and self.mode == "spdk": + busy_read = 1 + + sysctl_opts = { + "net.core.busy_poll": 0, + "net.core.busy_read": busy_read, + "net.core.somaxconn": 4096, + "net.core.netdev_max_backlog": 8192, + "net.ipv4.tcp_max_syn_backlog": 16384, + "net.core.rmem_max": 268435456, + "net.core.wmem_max": 268435456, + "net.ipv4.tcp_mem": "268435456 268435456 268435456", + "net.ipv4.tcp_rmem": "8192 1048576 33554432", + "net.ipv4.tcp_wmem": "8192 1048576 33554432", + "net.ipv4.route.flush": 1, + "vm.overcommit_memory": 1, + } + + for opt, value in sysctl_opts.items(): + self.sysctl_restore_dict.update({opt: self.exec_cmd(["sysctl", "-n", opt]).strip()}) + self.log_print(self.exec_cmd(["sudo", "sysctl", "-w", "%s=%s" % (opt, value)]).strip()) + def restore_services(self): self.log_print("Restoring services...") for service, state in self.svc_restore_dict.items(): cmd = "stop" if state == "inactive" else "start" self.exec_cmd(["sudo", "systemctl", cmd, service]) + def restore_sysctl(self): + self.log_print("Restoring sysctl settings...") + for opt, value in self.sysctl_restore_dict.items(): + self.log_print(self.exec_cmd(["sudo", "sysctl", "-w", "%s=%s" % (opt, value)]).strip()) + class Target(Server): def __init__(self, name, general_config, target_config): @@ -510,8 +543,15 @@ class Initiator(Server): self.ssh_connection.close() def exec_cmd(self, cmd, stderr_redirect=False): - # Redirect stderr to stdout thanks using get_pty option if needed + # In case one of the command elements contains whitespace and is not + # already quoted, # (e.g. when calling sysctl) quote it again to prevent expansion + # when sending to remote system. + for i, c in enumerate(cmd): + if (" " in c or "\t" in c) and not (c.startswith("'") and c.endswith("'")): + cmd[i] = '"%s"' % c cmd = " ".join(cmd) + + # Redirect stderr to stdout thanks using get_pty option if needed _, stdout, _ = self.ssh_connection.exec_command(cmd, get_pty=stderr_redirect) out = stdout.read().decode(encoding="utf-8") @@ -1203,6 +1243,8 @@ if __name__ == "__main__": i.copy_result_files(target_results_dir) target_obj.restore_services() + target_obj.restore_sysctl() for i in initiators: i.restore_services() + i.restore_sysctl() target_obj.parse_results(target_results_dir)