From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id CD8021C61D for ; Tue, 15 May 2018 03:55:05 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 May 2018 18:55:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,402,1520924400"; d="scan'208";a="39337759" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga007.fm.intel.com with ESMTP; 14 May 2018 18:55:04 -0700 Received: from fmsmsx158.amr.corp.intel.com (10.18.116.75) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 14 May 2018 18:55:04 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by fmsmsx158.amr.corp.intel.com (10.18.116.75) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 14 May 2018 18:55:04 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.40]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.240]) with mapi id 14.03.0319.002; Tue, 15 May 2018 09:55:02 +0800 From: "Wang, FeiX Y" To: "Rosen, Rami" , "dts@dpdk.org" Thread-Topic: [dts] [DTS][Patch V1 0/2] VF_performace_test_suite Thread-Index: AQHT6ybGbpbSRM9XeUy+a82GAHXYCaQvGyQAgADtQNA= Date: Tue, 15 May 2018 01:55:01 +0000 Message-ID: References: <1526271798-22666-1-git-send-email-feix.y.wang@intel.com> <9B0331B6EBBD0E4684FBFAEDA55776F958A249E9@HASMSX110.ger.corp.intel.com> In-Reply-To: <9B0331B6EBBD0E4684FBFAEDA55776F958A249E9@HASMSX110.ger.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dts] [DTS][Patch V1 0/2] VF_performace_test_suite X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2018 01:55:06 -0000 Hi, Rami Thanks for your correction, it was a mistake, I meant to use different macs= for different VF ports, will send v2 patch soon. Thanks Fei -----Original Message----- From: Rosen, Rami=20 Sent: Tuesday, May 15, 2018 3:43 AM To: Wang, FeiX Y ; dts@dpdk.org Cc: Wang, FeiX Y Subject: RE: [dts] [DTS][Patch V1 0/2] VF_performace_test_suite Hi, One comment, inline. -----Original Message----- From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of wang fei Sent: Monday, May 14, 2018 07:23 To: dts@dpdk.org Cc: Wang, FeiX Y Subject: [dts] [DTS][Patch V1 0/2] VF_performace_test_suite Add performance test for kernel PF + DPDK VF and DPDK PF + DPDK VF. Signed-off-by: wang fei --- tests/TestSuite_vf_perf.py | 340 +++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 340 insertions(+) create mode 100644 tests/TestSuite_vf_perf.py diff --git a/tests/TestSuite_vf_perf.py b/tests/TestSuite_vf_perf.py new fi= le mode 100644 index 0000000..6b36c8a --- /dev/null +++ b/tests/TestSuite_vf_perf.py @@ -0,0 +1,340 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2017 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without #=20 +modification, are permitted provided that the following conditions #=20 +are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS #=20 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT #=20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR #=20 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT #=20 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #=20 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT #=20 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #=20 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY #=20 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #=20 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #=20 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import re +import time +import string + +import utils +from test_case import TestCase +from pmd_output import PmdOutput +from etgen import IxiaPacketGenerator +from settings import HEADER_SIZE + +class TestVfPerf(TestCase, IxiaPacketGenerator): + + def set_up_all(self): + + self.tester.extend_external_packet_generator(TestVfPerf, self) + + self.dut_ports =3D self.dut.get_ports(self.nic) + self.verify(len(self.dut_ports) >=3D 2, "Insufficient ports") + + self.pf0 =3D self.dut_ports[0] + netdev =3D self.dut.ports_info[self.pf0]['port'] + self.pf0_socket =3D netdev.get_nic_socket() + + self.cores =3D self.dut.get_core_list("1S/6C/1T", socket=3Dself.pf= 0_socket) + self.verify(self.cores is not None, "Insufficient cores for the +testing") + + self.req_ports =3D eval(self.get_suite_cfg()['req_ports']) + assert self.req_ports in [2, 4], "Requested Ports Number Must Be 2= or 4" + + global valports + valports =3D [_ for _ in self.dut_ports if self.tester.get_local_p= ort(_) !=3D -1] + self.verify(len(valports) >=3D self.req_ports, "Insufficient=20 + active ports for testing") + + self.frame_sizes =3D [64, 128, 256, 512, 1024, 1518] + self.l3fwd_methods =3D ['lpm'] + + self.vf0_mac =3D "00:12:34:56:78:01" + self.vf1_mac =3D "00:12:34:56:78:02" + if self.req_ports =3D=3D 4: Shouldn't the MAC address of VF2 be different than the MAC address of VF1 ?= =20 + self.vf2_mac =3D "00:12:34:56:78:02" + self.vf3_mac =3D "00:12:34:56:78:03" + + self.l3fwd_test_results =3D {'header': [], 'data': []} + + self.dut.send_expect("sed -i -e 's/define RTE_TEST_RX_DESC_DEFAULT= .*$/" + + "define RTE_TEST_RX_DESC_DEFAULT 2048/' ./e= xamples/l3fwd/main.c", "#", 20) + self.dut.send_expect("sed -i -e 's/define RTE_TEST_TX_DESC_DEFAULT= .*$/" + + "define RTE_TEST_TX_DESC_DEFAULT 2048/' ./e= xamples/l3fwd/main.c", "#", 20) + out =3D self.dut.build_dpdk_apps("./examples/l3fwd", "USER_FLAGS= =3D-DAPP_LOOKUP_METHOD=3D1") + self.verify("Error" not in out, "compilation error 1") + self.verify("No such file" not in out, "compilation error 2") + + def set_up(self): + + self.setup_vf_env_flag =3D 0 + + def setup_vf_env(self, host_driver=3D'default'): + """ + require two PF ports, using kernel or dpdk driver, create 1 VF fro= m each PF. + """ + + self.used_dut_port_0 =3D self.dut_ports[0] + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_0, 1, host_= driver) + self.sriov_vfs_port_0 =3D + self.dut.ports_info[self.used_dut_port_0]['vfs_port'] + + self.used_dut_port_1 =3D self.dut_ports[1] + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_1, 1, host_= driver) + self.sriov_vfs_port_1 =3D + self.dut.ports_info[self.used_dut_port_1]['vfs_port'] + =20 + if self.req_ports =3D=3D 4: + self.used_dut_port_2 =3D self.dut_ports[2] + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_2, 1, h= ost_driver) + self.sriov_vfs_port_2 =3D + self.dut.ports_info[self.used_dut_port_2]['vfs_port'] + + self.used_dut_port_3 =3D self.dut_ports[3] + self.dut.generate_sriov_vfs_by_port(self.used_dut_port_3, 1, h= ost_driver) + self.sriov_vfs_port_3 =3D + self.dut.ports_info[self.used_dut_port_3]['vfs_port'] + + if host_driver !=3D 'igb_uio': + + pf_intf0 =3D self.dut.ports_info[0]['port'].get_interface_name= () + self.dut.send_expect("ip link set %s vf 0 mac %s" % (pf_intf0,= self.vf0_mac), "#") + pf_intf1 =3D self.dut.ports_info[1]['port'].get_interface_name= () + self.dut.send_expect("ip link set %s vf 0 mac %s" % (pf_intf1,= self.vf1_mac), "#") + if self.req_ports =3D=3D 4: + pf_intf2 =3D self.dut.ports_info[2]['port'].get_interface_= name() + self.dut.send_expect("ip link set %s vf 0 mac %s" % (pf_in= tf2, self.vf2_mac), "#") + pf_intf3 =3D self.dut.ports_info[3]['port'].get_interface_= name() + self.dut.send_expect("ip link set %s vf 0 mac %s" %=20 + (pf_intf3, self.vf3_mac), "#") + + #bind vf to igb_uio driver + try: + for port in self.sriov_vfs_port_0: + port.bind_driver('igb_uio') + for port in self.sriov_vfs_port_1: + port.bind_driver('igb_uio') + if self.req_ports =3D=3D 4: + for port in self.sriov_vfs_port_2: + port.bind_driver('igb_uio') + for port in self.sriov_vfs_port_3: + port.bind_driver('igb_uio') + + time.sleep(1) + + if host_driver =3D=3D 'igb_uio' and self.req_ports =3D=3D2: + # start testpmd without the two VFs on the host + self.host_testpmd =3D PmdOutput(self.dut) + eal_param =3D '--socket-mem=3D1024,1024 --file-prefix=3Dpf= -b %(vf0)s -b %(vf1)s' % {'vf0': self.sriov_vfs_port_0[0].pci, + = 'vf1': self.sriov_vfs_port_1[0].pci} + testpmd_cl =3D self.cores[0:2] + self.host_testpmd.start_testpmd(testpmd_cl, "", eal_param= =3Deal_param) + self.host_testpmd.execute_cmd('set vf mac addr 0 0 %s' % s= elf.vf0_mac) + self.host_testpmd.execute_cmd('set vf mac addr 1 0 %s' % s= elf.vf1_mac) + elif host_driver =3D=3D 'igb_uio' and self.req_ports =3D=3D4: + self.host_testpmd =3D PmdOutput(self.dut) + eal_param =3D '--socket-mem=3D1024,1024 --file-prefix=3Dpf= -b %(vf0)s -b %(vf1)s -b %(vf2)s -b %(vf3)s' % {'vf0': self.sriov_vfs_port= _0[0].pci, + 'vf1': self.sriov_vfs_port_1[0].pci, 'vf2': s= elf.sriov_vfs_port_2[0].pci, 'vf3': self.sriov_vfs_port_3[0].pci} + testpmd_cl =3D self.cores[0:4] + self.host_testpmd.start_testpmd(testpmd_cl, "", eal_param= =3Deal_param) + self.host_testpmd.execute_cmd('set vf mac addr 0 0 %s' % s= elf.vf0_mac) + self.host_testpmd.execute_cmd('set vf mac addr 1 0 %s' % s= elf.vf1_mac) + self.host_testpmd.execute_cmd('set vf mac addr 2 0 %s' % s= elf.vf2_mac) + self.host_testpmd.execute_cmd('set vf mac addr 3 0 %s' % s= elf.vf3_mac) + time.sleep(1) + + self.setup_vf_env_flag =3D 1 + + except Exception as e: + self.destroy_vf_env() + raise Exception(e) + + def destroy_vf_env(self): + """destroy the setup VFs""" + + if getattr(self, 'host_testpmd', None): + self.host_testpmd.execute_cmd('quit', '# ') + self.host_testpmd =3D None + + if getattr(self, 'used_dut_port_0', None) !=3D None: + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_0) + port =3D self.dut.ports_info[self.used_dut_port_0]['port'] + port.bind_driver() + self.used_dut_port_0 =3D None + + if getattr(self, 'used_dut_port_1', None) !=3D None: + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_1) + port =3D self.dut.ports_info[self.used_dut_port_1]['port'] + port.bind_driver() + self.used_dut_port_1 =3D None + + if getattr(self, 'used_dut_port_2', None) !=3D None: + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_2) + port =3D self.dut.ports_info[self.used_dut_port_2]['port'] + port.bind_driver() + self.used_dut_port_2 =3D None + + if getattr(self, 'used_dut_port_3', None) !=3D None: + self.dut.destroy_sriov_vfs_by_port(self.used_dut_port_3) + port =3D self.dut.ports_info[self.used_dut_port_3]['port'] + port.bind_driver() + self.used_dut_port_3 =3D None + + for port_id in self.dut_ports: + port =3D self.dut.ports_info[port_id]['port'] + port.bind_driver() + + self.setup_vf_env_flag =3D 0 + + def flows(self): + """ + Return a list of packets that implements the flows described in l3= fwd. + """ =20 + return [ + 'IP(src=3D"1.2.3.4",dst=3D"2.1.1.1")', + 'IP(src=3D"1.2.3.4",dst=3D"2.1.1.2")', + 'IP(src=3D"1.2.3.4",dst=3D"1.1.1.1")', + 'IP(src=3D"1.2.3.4",dst=3D"1.1.1.2")', + 'IP(src=3D"1.2.3.4",dst=3D"4.1.1.1")', + 'IP(src=3D"1.2.3.4",dst=3D"4.1.1.2")', + 'IP(src=3D"1.2.3.4",dst=3D"3.1.1.1")', + 'IP(src=3D"1.2.3.4",dst=3D"3.1.1.2")'] + + def perf_test(self, cmdline): + + l3fwd_session =3D self.dut.new_session() + + header_row =3D ["Frame", "mode", "Mpps", "%linerate"] + self.l3fwd_test_results['header'] =3D header_row + self.result_table_create(header_row) + self.l3fwd_test_results['data'] =3D [] + + dmac =3D [self.vf0_mac, self.vf1_mac] + smac =3D ["02:00:00:00:00:00", "02:00:00:00:00:01"] + if self.req_ports =3D=3D 4: + dmac.extend([self.vf2_mac, self.vf3_mac]) + smac.extend(["02:00:00:00:00:02", "02:00:00:00:00:03"]) + + for frame_size in self.frame_sizes: + + # Prepare traffic flow + payload_size =3D frame_size - HEADER_SIZE['ip'] -=20 + HEADER_SIZE['eth'] + + for _port in range(self.req_ports): + flows =3D ['Ether(dst=3D"%s", src=3D"%s")/%s/("X"*%d)' % (= dmac[_port], smac[_port], flow, payload_size) for flow in self.flows()[_por= t *2:(_port +1)*2]] + self.tester.scapy_append('wrpcap("dst%d.pcap", [%s])' %(va= lports[_port], string.join(flows,','))) + self.tester.scapy_execute() + + for mode in self.l3fwd_methods: + + info =3D "Executing l3fwd using %s mode, %d ports, %d fram= e size.\n" % (mode, self.req_ports, frame_size) + self.logger.info(info) + + if frame_size > 1518: + cmdline =3D cmdline + " --max-pkt-len %d" %=20 + frame_size + + out =3D l3fwd_session.send_expect(cmdline, "L3FWD:", 120) + + # Measure test + tgenInput =3D [] + + for rxPort in range(self.req_ports): + if rxPort % self.req_ports =3D=3D 0 or rxPort % self.r= eq_ports =3D=3D 2 : + txIntf =3D self.tester.get_local_port(valports[rxP= ort + 1]) + rxIntf =3D self.tester.get_local_port(valports[rxP= ort]) + tgenInput.append((txIntf, rxIntf, "dst%d.pcap" % v= alports[rxPort+1])) + elif rxPort % self.req_ports =3D=3D 1 or rxPort % self= .req_ports =3D=3D 3: + txIntf =3D self.tester.get_local_port(valports[rxP= ort - 1]) + rxIntf =3D self.tester.get_local_port(valports[rxP= ort]) + tgenInput.append((txIntf, rxIntf, "dst%d.pcap"=20 + % valports[rxPort-1])) + =20 + + _, pps =3D self.tester.traffic_generator_throughput(tgenIn= put, rate_percent=3D100, delay=3D60) + self.verify(pps > 0, "No traffic detected") + pps /=3D 1000000.0 + linerate =3D self.wirespeed(self.nic, frame_size, self.req= _ports) + pct =3D pps * 100 / linerate + + # Stop l3fwd + l3fwd_session.send_expect("^C", "#") + time.sleep(5) + + data_row =3D [frame_size, mode, str(pps), str(pct)] + self.result_table_add(data_row) + self.l3fwd_test_results['data'].append(data_row) + + self.dut.close_session(l3fwd_session) + self.result_table_print() + + + def measure_vf_performance(self, host_driver=3D'default'): + """start l3fwd and run the perf test""" + + time.sleep(10) + if host_driver =3D=3D 'igb_uio': + self.setup_vf_env(host_driver=3D'igb_uio') + else: + self.setup_vf_env(host_driver=3D'') + + vf0_pci =3D self.sriov_vfs_port_0[0].pci + vf1_pci =3D self.sriov_vfs_port_1[0].pci + if self.req_ports =3D=3D 4: + vf2_pci =3D self.sriov_vfs_port_2[0].pci + vf3_pci =3D self.sriov_vfs_port_3[0].pci + =20 + #for fvl10g, fvl40g, fvl25g, use 2c/2q per VF port for performance= test + if self.nic in ["fortville_25g", "fortville_spirit", "fortville_ea= gle"]: + + l3fwd_cl =3D self.cores[2:6] + core_mask =3D utils.create_mask(l3fwd_cl) + port_mask =3D utils.create_mask(self.dut_ports) + + cmdline =3D "./examples/l3fwd/build/l3fwd -c {0} -n 4 -w {1} -= w {2} -- -p {3} \ + --config '(0,0,{4}),(0,1,{5}),(1,0,{6}),(1,1,{7})' = ". \ + format(core_mask, vf0_pci, vf1_pci, port_mask, l3fw= d_cl[0], l3fwd_cl[1], l3fwd_cl[2], l3fwd_cl[3]) + if self.req_ports =3D=3D 4: + cmdline =3D "./examples/l3fwd/build/l3fwd -c {0} -n 4 -w {1= } -w {2} -w {3} -w {4} -- -p {5} \ + --config '(0,0,{6}),(1,0,{7}),(2,0,{8}),(3,0,{9})' = ". \ + format(core_mask, vf0_pci, vf1_pci, vf2_pci, vf3_pc= i, port_mask, l3fwd_cl[0], l3fwd_cl[1], l3fwd_cl[2], l3fwd_cl[3]) + else: + #for nnt, use 1c/1q per VF port for performance test + l3fwd_cl =3D self.cores[4:6] + core_mask =3D utils.create_mask(l3fwd_cl) + cmdline =3D "./examples/l3fwd/build/l3fwd -c {0} -n 4 -w {1} -= w {2} -- -p 0x3 \ + --config '(0,0,{3}),(1,0,{4})' ". \ + format(core_mask, vf0_pci, vf1_pci, l3fwd_cl[0], + l3fwd_cl[1]) + =20 + self.perf_test(cmdline) + + def test_perf_a_kernel_pf_dpdk_vf_performance(self): + =20 + self.measure_vf_performance(host_driver=3D'') + + def test_perf_b_dpdk_pf_dpdk_vf_performance(self): + + self.measure_vf_performance(host_driver=3D'igb_uio') + + def tear_down(self): + + if self.setup_vf_env_flag =3D=3D 1: + self.destroy_vf_env() + + for port_id in self.dut_ports: + self.dut.destroy_sriov_vfs_by_port(port_id) + # DPDK-1754 + intf =3D self.dut.ports_info[port_id]['intf'] + self.dut.send_expect("ethtool -s %s autoneg on" % intf, "# + ") + + def tear_down_all(self): + pass -- 2.7.4 Regards, Rami Rosen