From patchwork Fri Jul 29 11:35:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Harneet Singh X-Patchwork-Id: 114444 Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D81FBA04FD; Fri, 29 Jul 2022 13:35:32 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C7F9C4069C; Fri, 29 Jul 2022 13:35:32 +0200 (CEST) Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id CA72940151 for ; Fri, 29 Jul 2022 13:35:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1659094531; x=1690630531; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DuqkkR/CsfBsymEv+ro4oSQR8nZ/x2yHuGemEylG69s=; b=jP5a75Qd56FksOr5X9fJ33vk2nRj0SKyNdthlloD/dWVG+90uGrI81rM sX5js7paC3zH/KaN8jv5DYJp2RwyUPCZ0J9LrT4vzyqau4aP2HnZRbEKs R6f6AIC3Oi4HS+Z24NpVcsBVVslyfRCiedygqY2vQiXEm1Y44iQRuqIXA MXhgAbmiIAhiyPJjs547V77rMFqTqiY3mxh8GC6woUiV00bFJ1bn6ZBWX 8CwCiVdJUCvEw17ufgGhZibZf9aJ8jmyKLanRuA6tTacT2sdw1F/uGDLk kHr2J6q0TwoF9FTjKVFk+Fr1eP1csBipJ0y2uBT2QQXANgYJDyjE1zHwn A==; X-IronPort-AV: E=McAfee;i="6400,9594,10422"; a="350455210" X-IronPort-AV: E=Sophos;i="5.93,201,1654585200"; d="scan'208";a="350455210" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jul 2022 04:35:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,201,1654585200"; d="scan'208";a="669245941" Received: from silpixa00401183.ir.intel.com ([10.55.129.105]) by fmsmga004.fm.intel.com with ESMTP; 29 Jul 2022 04:35:28 -0700 From: harneet.singh@intel.com To: dts@dpdk.org Cc: Harneet Singh Subject: [PATCH v2] tests/power_throughput: modifying rst and adding throughput test py file Date: Fri, 29 Jul 2022 11:35:26 +0000 Message-Id: <20220729113526.243393-1-harneet.singh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220726131259.143233-1-harneet.singh@intel.com> References: <20220726131259.143233-1-harneet.singh@intel.com> MIME-Version: 1.0 X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org From: Harneet Singh 1: Created a py file for throughput test which will test the cpu frequency with different packet speeds. 2: Renaned the power throughput rst plan to match other power tests naming convention. 3: Modified the power throughput rst plan to match test cases. Signed-off-by: Harneet Singh Acked-by: Tadhg Kearney --- V2: - Added power_throughput_test_plan name in index.rst file and removed the older throughput test plan name as dts-doc-test failed in V1. - Formatted throughput_test.py file lines to max 88 characters as dts-format-test failed in V1. - Modified the Class name of throughput_test.py file -- --- test_plans/index.rst | 2 +- ...power_managerment_throughput_test_plan.rst | 45 --- test_plans/power_throughput_test_plan.rst | 51 +++ tests/TestSuite_power_throughput.py | 329 ++++++++++++++++++ 4 files changed, 381 insertions(+), 46 deletions(-) delete mode 100644 test_plans/power_managerment_throughput_test_plan.rst create mode 100644 test_plans/power_throughput_test_plan.rst create mode 100644 tests/TestSuite_power_throughput.py diff --git a/test_plans/index.rst b/test_plans/index.rst index a78dd0f5..b0ec622d 100644 --- a/test_plans/index.rst +++ b/test_plans/index.rst @@ -190,6 +190,7 @@ The following are the test plans for the DPDK DTS automated test system. power_pbf_test_plan power_pstate_test_plan power_telemetry_test_plan + power_throughput_test_plan vmdq_test_plan vf_l3fwd_test_plan softnic_test_plan @@ -271,7 +272,6 @@ The following are the test plans for the DPDK DTS automated test system. flow_classify_test_plan dpdk_hugetlbfs_mount_size_test_plan nic_single_core_perf_test_plan - power_managerment_throughput_test_plan iavf_test_plan packet_capture_test_plan packet_ordering_test_plan diff --git a/test_plans/power_managerment_throughput_test_plan.rst b/test_plans/power_managerment_throughput_test_plan.rst deleted file mode 100644 index 4005831d..00000000 --- a/test_plans/power_managerment_throughput_test_plan.rst +++ /dev/null @@ -1,45 +0,0 @@ -.. SPDX-License-Identifier: BSD-3-Clause - Copyright(c) 2019 Intel Corporation - -====================================== -Power managerment throughput test plan -====================================== - -This test plan test cpu frequence changed according io workloads with l3fwd-power sample. -The cpu frequency status depends on NIC and CPU type. - -Prerequisites -============= - -1. Update Grub:: - - Add "intel_pstate=disable" in kernel options. - -2. BIOS configuration as below:: - - CPU mode : "Power" - Workload configuratuion:"IO sensitive" - Hardware Power : "Disabled" - Speedstep : "Enabled" - Turbo : "Enabled" - C-stats:C0/C1 - C6 : "Enabled" - -Test Case1: Check the CPU frequency can change according differernt packet speed -================================================================================ - -1. Check that you are using the "acpi-cpufreq" driver by command "cpufreq-info". - -2. CPU frequency controlled by userspace by command "cpupower frequency-set -g userspace". - -3. Bind one nic port to igb_uio, launch l3fwd-power sample, one core used for one port:: - - .//examples/dpdk-l3fwd-power -c 0xc000000 -n 4 -- -P -p 0x01 --config '(0,0,27)' - -4. Send packets by packet generator with high speed, check the used cpu frequency is almost 100%:: - - cat /sys/devices/system/cpu/cpu27/cpufreq/cpuinfo_cur_freq - -5. Send packets by packet generator with low speed, the CPU frequency will reduce about 50%:: - - cat /sys/devices/system/cpu/cpu27/cpufreq/cpuinfo_cur_freq \ No newline at end of file diff --git a/test_plans/power_throughput_test_plan.rst b/test_plans/power_throughput_test_plan.rst new file mode 100644 index 00000000..dbb9bf0e --- /dev/null +++ b/test_plans/power_throughput_test_plan.rst @@ -0,0 +1,51 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(c) 2019 Intel Corporation + +====================================== +Power managerment throughput test plan +====================================== + +This test plan test cpu frequency changed according io workloads with l3fwd-power sample. +The cpu frequency status depends on traffic speed. + +Prerequisites +============= + +1. Update Grub:: + + Add "intel_pstate=disable" in kernel options. + +2. BIOS configuration as below:: + + CPU mode : "Power" + Workload configuratuion:"IO sensitive" + Hardware Power : "Disabled" + Speedstep : "Enabled" + Turbo : "Enabled" + C-stats:C0/C1 + C6 : "Enabled" + +3. Let user space can control the CPU frequency:: + + cpupower frequency-set -g userspace + +Test Case 1: Check the CPU frequency with high traffic speed +================================================================================ + +1. Bind one nic port to igb_uio, launch l3fwd-power sample with sacle mode, one core used for one port:: + + .//examples/dpdk-l3fwd-power -c 0x6 -n 1 -- --pmd-mgmt scale --max-empty-poll 128 -p 0x1 -P --config="(0,0,2)" + +2. Send packets by packet generator with high speed, check the cpu frequency it should be equal or below turbo max frequency + and be higher than p1. + + cat /sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq + +Test Case 2: Check the CPU frequency with low traffic speed +================================================================================ + +1. same as Test Case 1 step 1. + +2. Send packets by packet generator with low speed, check the cpu frequency it should be below p1. + + cat /sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq \ No newline at end of file diff --git a/tests/TestSuite_power_throughput.py b/tests/TestSuite_power_throughput.py new file mode 100644 index 00000000..db5a058f --- /dev/null +++ b/tests/TestSuite_power_throughput.py @@ -0,0 +1,329 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2010-2020 Intel Corporation +# + +""" +DPDK Test suite. +l3fwd-power test suite. +""" +import os +import time +import traceback +from ast import And +from copy import deepcopy +from pprint import pformat + +from framework.exception import VerifyFailure +from framework.packet import Packet +from framework.pktgen import TRANSMIT_CONT +from framework.settings import HEADER_SIZE +from framework.test_case import TestCase +from framework.utils import create_mask as dts_create_mask + + +class TestPowerThroughput(TestCase): + output_path = "/tmp" + + @property + def target_dir(self): + # get absolute directory of target source code + target_dir = ( + "/root" + self.dut.base_dir[1:] + if self.dut.base_dir.startswith("~") + else self.dut.base_dir + ) + return target_dir + + def d_con(self, cmd): + _cmd = [cmd, "# ", 10] if isinstance(cmd, str) else cmd + return self.dut.send_expect(*_cmd) + + def d_a_con(self, cmd): + _cmd = [cmd, "# ", 10] if isinstance(cmd, str) else cmd + return self.dut.alt_session.send_expect(*_cmd) + + def get_pkt_len(self, pkt_type, frame_size=64): + headers_size = sum([HEADER_SIZE[x] for x in ["eth", "ip", pkt_type]]) + pktlen = frame_size - headers_size + return pktlen + + def config_stream(self, dmac): + pkt_config = { + "type": "UDP", + "pkt_layers": { + "ether": {"dst": dmac}, + "raw": {"payload": ["58"] * self.get_pkt_len("udp")}, + }, + } + values = pkt_config + pkt_type = values.get("type") + pkt_layers = values.get("pkt_layers") + pkt = Packet(pkt_type=pkt_type) + for layer in list(pkt_layers.keys()): + pkt.config_layer(layer, pkt_layers[layer]) + return pkt.pktgen.pkt + + def add_stream_to_pktgen(self, option): + stream_ids = [] + topos = [[0, 0]] + for txport, rxport in topos: + _option = deepcopy(option) + dmac = self.dut.get_mac_address(self.dut_ports[txport]) + pkt = self.config_stream(dmac) + _option["pcap"] = pkt + stream_id = self.tester.pktgen.add_stream(txport, rxport, pkt) + self.tester.pktgen.config_stream(stream_id, _option) + stream_ids.append(stream_id) + return stream_ids + + def run_traffic(self, option, traffic_rate): + # clear streams before add new streams + self.tester.pktgen.clear_streams() + # set stream into pktgen + stream_option = { + "stream_config": { + "txmode": {}, + "transmit_mode": TRANSMIT_CONT, + "rate": float(traffic_rate), + } + } + stream_ids = self.add_stream_to_pktgen(stream_option) + # run pktgen traffic + traffic_opt = option.get("traffic_opt") + result = self.tester.pktgen.measure(stream_ids, traffic_opt) + #self.tester.pktgen.measure(stream_ids, traffic_opt) + #return result + + def prepare_binary(self, name): + example_dir = "examples/" + name + out = self.dut.build_dpdk_apps("./" + example_dir) + return os.path.join(self.target_dir, self.dut.apps_name[os.path.basename(name)]) + + def get_cores_mask(self, config): + ports_socket = self.dut.get_numa_id(self.dut.get_ports()[0]) + mask = dts_create_mask(self.dut.get_core_list(config, socket=ports_socket)) + return mask + + def init_l3fwd_power(self): + self.l3fwd_power = self.prepare_binary("l3fwd-power") + + def start_l3fwd_power(self, core_config="1S/2C/1T"): + core_mask, core = "0x6", 2 + option = ( + " " + "-c {core_mask} " + "-n {mem_channel} " + "-- " + "--pmd-mgmt scale " + "--max-empty-poll 128 " + "-p 0x1 " + "-P " + '--config="(0,0,{core})" ' + ).format( + **{ + "core_mask": core_mask, + "core": core, + "mem_channel": self.dut.get_memory_channels(), + } + ) + prompt = "L3FWD_POWER: entering main telemetry loop" + cmd = [" ".join([self.l3fwd_power, option]), prompt, 60] + self.d_con(cmd) + self.is_l3fwd_on = True + + def close_l3fwd_power(self): + if not self.is_l3fwd_on: + return + cmd = "^C" + self.d_con(cmd) + + + def get_sys_power_driver(self): + drv_file = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver" + output = self.d_a_con("cat " + drv_file) + if not output: + msg = "unknown power driver" + raise VerifyFailure(msg) + drv_name = output.splitlines()[0].strip() + return drv_name + + def query_cpu_freq (self): + cmd = ";".join( + ["cat /sys/devices/system/cpu/cpu{0}/cpufreq/scaling_cur_freq"] + ).format(2) + output = self.d_a_con(cmd) + if not output: + self.scaling_cur_freq = 0 + else: + self.scaling_cur_freq = round(int(output)) + + def get_turbo_max_freq_using_msr(self): + cmd = "rdmsr -a 0x1ad" + output = self.d_a_con(cmd) + # extracting last 2 digits which holds the max freq hexa value + max_freq_hexa_value = output[-2:] + # Converting hexadecimal string to decimal + turbo_max_msr_freq = int(max_freq_hexa_value, 16) + # Converting to mhz + turbo_max_msr_freq = turbo_max_msr_freq * 100 + return turbo_max_msr_freq + + def get_p1_freq_as_int(self): + cmd = "cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" + output = self.d_a_con(cmd) + if not output: + return 0 + else: + # Extracting first 4 digits as rest of them are decimal numbers + output = int(str(output)[:4]) + # Since turbo is on and pstate disabled to extract p1 we need to + # subtract 1 from the output value as 1 here signifies turbo on. + # ie if p1 is 2300 the output will be 2301 + output = output - 1 + return output + + def check_core_scaling_high_traffic_results(self): + cpu_p1_freq = self.get_p1_freq_as_int() + # Extracting first 4 digits as rest of them are decimal numbers + scaling_cur_freq_mhz = int(str(self.scaling_cur_freq)[:4]) + # scaling freq should be between turbo max(inclusive) and p1 + if self.turbo_max_freq_mhz >= scaling_cur_freq_mhz and \ + cpu_p1_freq < scaling_cur_freq_mhz: + self.msg = 'Test core scaling max traffic successful !!!' + else: + self.msg = 'Test failed because current cpu freq({0} mhz) is not smaller ' \ + + 'or equal to turbo max freq({1} mhz) and not higher than p1({2} mhz)' + self.msg = self.msg.format(scaling_cur_freq_mhz, self.turbo_max_freq_mhz, + cpu_p1_freq) + raise VerifyFailure(self.msg) + + def check_core_scaling_low_traffic_results(self): + cpu_p1_freq = self.get_p1_freq_as_int() + # Extracting first 4 digits as rest of them are decimal numbers + scaling_cur_freq_mhz = int(str(self.scaling_cur_freq)[:4]) + # freq should be p1 or lower than p1 + if cpu_p1_freq >= scaling_cur_freq_mhz: + self.msg = 'Test core scaling low traffic successful !!!' + else: + self.msg = 'Test failed because current cpu freq({0} mhz) is not lower ' \ + + 'or equal to p1({1} mhz)' + self.msg = self.msg.format(scaling_cur_freq_mhz, cpu_p1_freq) + raise VerifyFailure(self.msg) + + def verify_core_scaling_high_traffic(self): + """ + Check core scaling with max(rate:100) injected throughput + """ + except_content = None + try: + self.start_l3fwd_power() + duration = 10 + option = { + "traffic_opt": { + "method": "throughput", + "interval": duration - 2, + "duration": duration, + 'callback': self.query_cpu_freq} + } + # set traffic rate + traffic_rate = 100.0 + # run traffic with specified rate + self.run_traffic(option, traffic_rate) + time.sleep(5) + # check test result + # NOTE: using msr to get max turbo freq value because + # in intel_pstate=disabled we can't get the exact value of max turbo + # freq of core ie. if p1 is 2300 and we extract cpuinfo_max_freq + # we get 2301 that 1 at end indicates that turbo is on but + # doesn't give max freq we can go on high traffic. + self.turbo_max_freq_mhz = self.get_turbo_max_freq_using_msr() + self.check_core_scaling_high_traffic_results() + except Exception as e: + self.logger.error(traceback.format_exc()) + except_content = e + finally: + self.close_l3fwd_power() + + # check verify result + if except_content: + raise VerifyFailure(except_content) + else: + self.logger.info(self.msg) + + def verify_core_scaling_low_traffic(self): + """ + Check core scaling with low(rate:5) injected throughput + """ + except_content = None + try: + self.start_l3fwd_power() + duration = 10 + option = { + "traffic_opt": { + "method": "throughput", + "interval": duration - 2, + "duration": duration, + 'callback': self.query_cpu_freq} + } + traffic_rate = 5.0 + self.run_traffic(option, traffic_rate) + time.sleep(5) + # check test result + self.turbo_max_freq_mhz = self.get_turbo_max_freq_using_msr() + self.check_core_scaling_low_traffic_results() + except Exception as e: + self.logger.error(traceback.format_exc()) + except_content = e + finally: + self.close_l3fwd_power() + + # check verify result + if except_content: + raise VerifyFailure(except_content) + else: + self.logger.info(self.msg) + + def verify_power_driver(self): + expected_drv = "acpi-cpufreq" + power_drv = self.get_sys_power_driver() + msg = "{0} should work with {1} driver on DUT".format( + self.suite_name, expected_drv + ) + self.verify(power_drv == expected_drv, msg) + + def preset_test_environment(self): + self.is_l3fwd_on = None + # init binary + self.init_l3fwd_power() + + # + # Test cases. + # + + def set_up_all(self): + """ + Run at the start of each test suite. + """ + self.verify_power_driver() + self.dut_ports = self.dut.get_ports(self.nic) + self.verify(len(self.dut_ports) >= 2, "Not enough ports") + # prepare testing environment + self.preset_test_environment() + + def tear_down_all(self): + """Run after each test suite.""" + pass + + def set_up(self): + """Run before each test case.""" + pass + + def tear_down(self): + """Run after each test case.""" + self.dut.kill_all() + + def test_perf_core_scaling_low_taffic(self): + self.verify_core_scaling_low_traffic() + + def test_perf_core_scaling_high_taffic(self): + self.verify_core_scaling_high_traffic()