From: "Ma, LihongX" <lihongx.ma@intel.com>
To: "Tu, Lijuan" <lijuan.tu@intel.com>, "dts@dpdk.org" <dts@dpdk.org>
Cc: "Wang, Yinan" <yinan.wang@intel.com>
Subject: Re: [dts] [PATCH V1 2/2][vhost gro] tests: add testsuite vhost gro
Date: Wed, 10 Jul 2019 06:21:14 +0000 [thread overview]
Message-ID: <BE1E572D0441E34284F1F8B7AC28F1970BADDABB@SHSMSX101.ccr.corp.intel.com> (raw)
In-Reply-To: <8CE3E05A3F976642AAB0F4675D0AD20E0BADE9DE@SHSMSX101.ccr.corp.intel.com>
Hi,lijuan
agree with you, and I will optimization code with gro , gso and exception path on later.
-----Original Message-----
From: Tu, Lijuan
Sent: Wednesday, July 10, 2019 1:55 PM
To: Ma, LihongX <lihongx.ma@intel.com>; dts@dpdk.org
Cc: Wang, Yinan <yinan.wang@intel.com>; Ma, LihongX <lihongx.ma@intel.com>
Subject: RE: [dts] [PATCH V1 2/2][vhost gro] tests: add testsuite vhost gro
1, why the file name is different with the class name? basically, the suite name is the file name 2, if your suite name is same as your config file name , the framework will load configuration, so there is no need to parse configuration file at test suite level.
For example:
If your suite file is TestSuite_dpdk_gro_lib.py, your configuration file should be dpdk_gro_lib.cfg.
And your class name should be" TestDPDKGROLib"
> -----Original Message-----
> From: dts [mailto:dts-bounces@dpdk.org] On Behalf Of lihong
> Sent: Thursday, July 4, 2019 5:42 AM
> To: dts@dpdk.org
> Cc: Wang, Yinan <yinan.wang@intel.com>; Ma, LihongX
> <lihongx.ma@intel.com>
> Subject: [dts] [PATCH V1 2/2][vhost gro] tests: add testsuite vhost
> gro
>
> Signed-off-by: lihong <lihongx.ma@intel.com>
> ---
> tests/TestSuite_dpdk_gro_lib.py | 381
> ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 381 insertions(+)
> create mode 100644 tests/TestSuite_dpdk_gro_lib.py
>
> diff --git a/tests/TestSuite_dpdk_gro_lib.py
> b/tests/TestSuite_dpdk_gro_lib.py new file mode 100644 index
> 0000000..e3561c0
> --- /dev/null
> +++ b/tests/TestSuite_dpdk_gro_lib.py
> @@ -0,0 +1,381 @@
> +# BSD LICENSE
> +#
> +# Copyright(c) <2019> Intel Corporation.
> +# All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions
> +# 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 #
> +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT #
> +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> FOR #
> +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT #
> +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL, #
> +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> #
> +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> USE, #
> +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY #
> +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #
> +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
> USE #
> +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +"""
> +DPDK Test suite.
> +
> +Vhost gro test suite.
> +"""
> +import re
> +import time
> +import utils
> +from test_case import TestCase
> +from virt_common import VM
> +from config import UserConf
> +
> +
> +class TestVhostGRO(TestCase):
> +
> + def set_up_all(self):
> + # This suite will not use the port config in ports.cfg
> + # it will use the port config in vhost_gro.cfg
> + # And it need two interface reconnet in DUT
> + # Get and verify the ports
> + self.dut_ports = self.dut.get_ports()
> + self.cores = self.dut.get_core_list("1S/2C/1T", socket=1)
> + # unbind the port which config in ports.cfg
> + for i in self.dut_ports:
> + port = self.dut.ports_info[i]['port']
> + port.bind_driver()
> +
> + # get and bind the port config in vhost_gro.cfg
> + config = UserConf('conf/vhost_gro.cfg')
> + conf = config.conf
> + section = config.get_sections()
> + self.verify('peerconf' in section,
> + 'Pls config peer info about intf in conf file vhost_gro.cfg')
> + params = conf._sections['peerconf']
> + self.pci = params['pci']
> + self.pci_drv = params['pci_drv']
> + self.peer_pci = params['peer']
> + self.nic_in_kernel = params['peer_intf']
> + self.dut.send_expect(
> + "./usertools/dpdk-devbind.py -b igb_uio %s" %
> + self.pci, '#', 30)
> +
> + # Set the params for VM
> + self.virtio_ip1 = "1.1.1.2"
> + self.virtio_mac1 = "52:54:00:00:00:01"
> + self.memory_channel = self.dut.get_memory_channels()
> + if len(set([int(core['socket']) for core in self.dut.cores])) == 1:
> + self.socket_mem = '1024'
> + else:
> + self.socket_mem = '1024,1024'
> + self.prepare_dpdk()
> +
> + def set_up(self):
> + #
> + # Run before each test case.
> + #
> + # Clean the execution ENV
> + self.dut.send_expect("rm -rf ./vhost-net*", "#")
> + self.dut.send_expect("killall -s INT testpmd", "#")
> + self.dut.send_expect("killall -s INT qemu-system-x86_64",
> + "#")
> +
> + def launch_testpmd_gro_on(self, mode=1):
> + #
> + # Launch the vhost sample with different parameters
> + # mode 1 : tcp traffic light mode
> + # mode 2 : tcp traffic heavy mode
> + # mode 3 : vxlan traffic light mode
> + # mode 4 : tcp traffic flush 4
> + self.testcmd = self.target + "/app/testpmd -c %s -n %d
> + --socket-mem %s
> --legacy-mem" \
> + + " --vdev 'net_vhost0,iface=vhost-net,queues=1' -- -i
> + --enable-hw-
> vlan-strip --tx-offloads=0x00" \
> + + " --txd=1024 --rxd=1024"
> + self.coremask = utils.create_mask(self.cores)
> + self.testcmd_start = self.testcmd % (
> + self.coremask, self.memory_channel, self.socket_mem)
> + self.vhost_user = self.dut.new_session(suite="user")
> + self.vhost_user.send_expect(self.testcmd_start, "testpmd> ", 120)
> + self.vhost_user.send_expect("set fwd csum", "testpmd> ", 120)
> + self.vhost_user.send_expect("stop", "testpmd> ", 120)
> + self.vhost_user.send_expect("port stop 0", "testpmd> ", 120)
> + self.vhost_user.send_expect("port stop 1", "testpmd> ", 120)
> + self.vhost_user.send_expect("csum set tcp hw 0", "testpmd> ", 120)
> + self.vhost_user.send_expect("csum set ip hw 0", "testpmd> ", 120)
> + self.vhost_user.send_expect("csum set tcp hw 1", "testpmd> ", 120)
> + self.vhost_user.send_expect("csum set ip hw 1", "testpmd> ", 120)
> + if(mode == 1):
> + self.vhost_user.send_expect("set port 0 gro on", "testpmd> ", 120)
> + self.vhost_user.send_expect("set gro flush 1", "testpmd> ", 120)
> + if(mode == 2):
> + self.vhost_user.send_expect("set port 0 gro on", "testpmd> ", 120)
> + self.vhost_user.send_expect("set gro flush 2", "testpmd> ", 120)
> + if (mode == 3):
> + self.vhost_user.send_expect("csum parse-tunnel on 1",
> + "testpmd> ",
> 120)
> + self.vhost_user.send_expect("csum parse-tunnel on 0",
> + "testpmd> ",
> 120)
> + self.vhost_user.send_expect("csum set outer-ip hw 0",
> + "testpmd> ",
> 120)
> + self.vhost_user.send_expect("set port 0 gro on", "testpmd> ", 120)
> + self.vhost_user.send_expect("set gro flush 2", "testpmd> ", 120)
> + else:
> + self.vhost_user.send_expect("set port 0 gro on", "testpmd> ", 120)
> + self.vhost_user.send_expect("set gro flush 4", "testpmd> ", 120)
> + self.vhost_user.send_expect("port start 0", "testpmd> ", 120)
> + self.vhost_user.send_expect("port start 1", "testpmd> ", 120)
> + self.vhost_user.send_expect("start", "testpmd> ", 120)
> +
> + def set_testpmd_gro_off(self):
> + #
> + # Launch the vhost sample with different parameters
> + #
> + self.vhost_user.send_expect("stop", "testpmd> ", 120)
> + self.vhost_user.send_expect("set port 0 gro off", "testpmd> ", 120)
> + self.vhost_user.send_expect("start", "testpmd> ", 120)
> +
> + def quit_testpmd(self):
> + # Quit testpmd and close temp ssh session
> + self.vhost_user.send_expect("quit", "#", 120)
> + self.dut.close_session(self.vhost_user)
> +
> + def config_kernel_nic_host(self, mode=1):
> + if (mode == 0):
> + self.dut.send_expect("ip netns del ns1", "#")
> + self.dut.send_expect("ip netns add ns1", "#")
> + self.dut.send_expect(
> + "ip link set %s netns ns1" %
> + self.nic_in_kernel, "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 ifconfig %s 1.1.1.8 up" %
> + self.nic_in_kernel, "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 ethtool -K %s tso on" %
> + self.nic_in_kernel, "#")
> + if (mode == 1):
> + self.dut.send_expect("ip netns del ns1", "#")
> + self.dut.send_expect("ip netns add ns1", "#")
> + self.dut.send_expect(
> + "ip link set %s netns ns1" %
> + self.nic_in_kernel, "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 ifconfig %s 1.1.2.4/24 up" %
> + self.nic_in_kernel, "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 ip link add vxlan1 type vxlan id
> + 42 dev %s
> dstport 4789" %
> + self.nic_in_kernel, "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 bridge fdb append to
> + 00:00:00:00:00:00 dst
> 1.1.2.3 dev vxlan1", "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 ip addr add 50.1.1.1/24 dev vxlan1", "#")
> + self.dut.send_expect(
> + "ip netns exec ns1 ip link set up dev vxlan1", "#")
> +
> + def prepare_dpdk(self):
> + #
> + # Changhe the testpmd checksum fwd code for mac change
> + self.dut.send_expect(
> + "cp ./app/test-pmd/csumonly.c ./app/test-pmd/csumonly_backup.c",
> + "#")
> + self.dut.send_expect(
> +
> "cp ./drivers/net/vhost/rte_eth_vhost.c
> ./drivers/net/vhost/rte_eth_vhost-
> backup.c",
> + "#")
> + self.dut.send_expect(
> + "sed -i '/ether_addr_copy(&peer_eth/i\#if 0' ./app/test-
> pmd/csumonly.c", "#")
> + self.dut.send_expect(
> + "sed -i '/parse_ethernet(eth_hdr, &info/i\#endif'
> + ./app/test-
> pmd/csumonly.c", "#")
> + # change offload of vhost
> + tx_offload = 'DEV_TX_OFFLOAD_VLAN_INSERT | ' + \
> + 'DEV_TX_OFFLOAD_UDP_CKSUM | ' + \
> + 'DEV_TX_OFFLOAD_TCP_CKSUM | ' + \
> + 'DEV_TX_OFFLOAD_IPV4_CKSUM | ' + \
> + 'DEV_TX_OFFLOAD_TCP_TSO;'
> + rx_offload = 'DEV_RX_OFFLOAD_VLAN_STRIP | ' + \
> + 'DEV_RX_OFFLOAD_TCP_CKSUM | ' + \
> + 'DEV_RX_OFFLOAD_UDP_CKSUM | ' + \
> + 'DEV_RX_OFFLOAD_IPV4_CKSUM | ' + \
> + 'DEV_RX_OFFLOAD_TCP_LRO;'
> + self.dut.send_expect(
> + "sed -i 's/DEV_TX_OFFLOAD_VLAN_INSERT;/%s/'
> drivers/net/vhost/rte_eth_vhost.c" % tx_offload, "#")
> + self.dut.send_expect(
> + "sed -i 's/DEV_RX_OFFLOAD_VLAN_STRIP;/%s/'
> drivers/net/vhost/rte_eth_vhost.c" % rx_offload, "#")
> + self.dut.build_install_dpdk(self.dut.target)
> +
> + def unprepare_dpdk(self):
> + # Recovery the DPDK code to original
> + self.dut.send_expect(
> + "cp ./app/test-pmd/csumonly_backup.c
> + ./app/test-pmd/csumonly.c
> ",
> + "#")
> + self.dut.send_expect(
> + "cp ./drivers/net/vhost/rte_eth_vhost-
> backup.c ./drivers/net/vhost/rte_eth_vhost.c ",
> + "#")
> + self.dut.send_expect("rm -rf ./app/test-pmd/csumonly_backup.c", "#")
> + self.dut.send_expect("rm -rf
> + ./drivers/net/vhost/rte_eth_vhost-
> backup.c", "#")
> + self.dut.build_install_dpdk(self.dut.target)
> +
> + def start_vm(self):
> + self.vm1 = VM(self.dut, 'vm0', 'vhost_gro')
> + vm_params_1 = {}
> + vm_params_1['driver'] = 'vhost-user'
> + vm_params_1['opt_path'] = './vhost-net'
> + vm_params_1['opt_mac'] = self.virtio_mac1
> + vm_params_1[
> + 'opt_settings'] =
> 'mrg_rxbuf=on,csum=off,gso=off,host_tso4=on,guest_tso4=on'
> + self.vm1.set_vm_device(**vm_params_1)
> + try:
> + self.vm1_dut = self.vm1.start()
> + if self.vm1_dut is None:
> + raise Exception("Set up VM ENV failed")
> + except Exception as e:
> + print utils.RED("Failure for %s" % str(e))
> + self.vm1_dut.restore_interfaces()
> +
> + def iperf_result_verify(self, run_info):
> + '''
> + Get the iperf test result
> + '''
> + fmsg = self.dut.send_expect("cat /root/iperf_client.log", "#")
> + print fmsg
> + iperfdata = re.compile('[\d+]*.[\d+]* [M|G|K]bits/sec').findall(fmsg)
> + print iperfdata
> + self.verify(iperfdata, 'There no data about this case')
> + self.result_table_create(['Data', 'Unit'])
> + results_row = [run_info]
> + results_row.append(iperfdata[-1])
> + self.result_table_add(results_row)
> + self.result_table_print()
> + self.output_result = "Iperf throughput is %s" % iperfdata[-1]
> + self.logger.info(self.output_result)
> +
> + def test_vhost_gro_tcp_lightmode(self):
> + self.config_kernel_nic_host(0)
> + self.launch_testpmd_gro_on()
> + self.start_vm()
> + time.sleep(5)
> + self.dut.get_session_output(timeout=2)
> + # Get the virtio-net device name
> + for port in self.vm1_dut.ports_info:
> + self.vm1_intf = port['intf']
> + # Start the Iperf test
> + self.vm1_dut.send_expect('ifconfig -a', '#', 30)
> + self.vm1_dut.send_expect(
> + 'ifconfig %s %s' %
> + (self.vm1_intf, self.virtio_ip1), '#', 10)
> + self.vm1_dut.send_expect('ifconfig %s up' % self.vm1_intf, '#', 10)
> + self.vm1_dut.send_expect(
> + 'ethtool -K %s gro off' % (self.vm1_intf), '#', 10)
> + self.vm1_dut.send_expect('iperf -s', '', 10)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + self.dut.send_expect(
> + 'ip netns exec ns1 iperf -c %s -i 1 -t 10 -P 1> /root/iperf_client.log &' %
> + (self.virtio_ip1), '', 180)
> + time.sleep(30)
> + self.iperf_result_verify('GRO lib')
> + print "the GRO lib %s " % (self.output_result)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + # Turn off DPDK GRO lib and Kernel GRO off
> + self.set_testpmd_gro_off()
> + self.dut.send_expect(
> + 'ip netns exec ns1 iperf -c %s -i 1 -t 10 -P 1 >
> + /root/iperf_client.log
> &' %
> + (self.virtio_ip1), '', 180)
> + time.sleep(30)
> + self.iperf_result_verify('Kernel GRO')
> + print "the Kernel GRO %s " % (self.output_result)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + self.quit_testpmd()
> + self.dut.send_expect("killall -s INT qemu-system-x86_64",
> + "#")
> +
> + def test_vhost_gro_tcp_heavymode(self):
> + self.config_kernel_nic_host(0)
> + self.heavymode = 2
> + self.launch_testpmd_gro_on(self.heavymode)
> + self.start_vm()
> + time.sleep(5)
> + self.dut.get_session_output(timeout=2)
> + # Get the virtio-net device name
> + for port in self.vm1_dut.ports_info:
> + self.vm1_intf = port['intf']
> + # Start the Iperf test
> + self.vm1_dut.send_expect('ifconfig -a', '#', 30)
> + self.vm1_dut.send_expect(
> + 'ifconfig %s %s' %
> + (self.vm1_intf, self.virtio_ip1), '#', 10)
> + self.vm1_dut.send_expect('ifconfig %s up' % self.vm1_intf, '#', 10)
> + self.vm1_dut.send_expect(
> + 'ethtool -K %s gro off' %
> + (self.vm1_intf), '#', 10)
> + self.vm1_dut.send_expect('iperf -s', '', 10)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + self.dut.send_expect(
> + 'ip netns exec ns1 iperf -c %s -i 1 -t 10 -P 1> /root/iperf_client.log &' %
> + (self.virtio_ip1), '', 180)
> + time.sleep(30)
> + self.iperf_result_verify('GRO lib')
> + print "the GRO lib %s " % (self.output_result)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + self.quit_testpmd()
> + self.dut.send_expect("killall -s INT qemu-system-x86_64",
> + "#")
> +
> + def test_vhost_gro_tcp_heavymode_flush4(self):
> + self.config_kernel_nic_host(0)
> + self.heavymode = 4
> + self.launch_testpmd_gro_on(self.heavymode)
> + self.start_vm()
> + time.sleep(5)
> + self.dut.get_session_output(timeout=2)
> + # Get the virtio-net device name
> + for port in self.vm1_dut.ports_info:
> + self.vm1_intf = port['intf']
> + # Start the Iperf test
> + self.vm1_dut.send_expect('ifconfig -a', '#', 30)
> + self.vm1_dut.send_expect(
> + 'ifconfig %s %s' %
> + (self.vm1_intf, self.virtio_ip1), '#', 10)
> + self.vm1_dut.send_expect('ifconfig %s up' % self.vm1_intf, '#', 10)
> + self.vm1_dut.send_expect(
> + 'ethtool -K %s gro off' %
> + (self.vm1_intf), '#', 10)
> + self.vm1_dut.send_expect('iperf -s', '', 10)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + self.dut.send_expect(
> + 'ip netns exec ns1 iperf -c %s -i 1 -t 10 -P 1> /root/iperf_client.log &' %
> + (self.virtio_ip1), '', 180)
> + time.sleep(30)
> + self.iperf_result_verify('GRO lib')
> + print "the GRO lib %s " % (self.output_result)
> + self.dut.send_expect('rm /root/iperf_client.log', '#', 10)
> + self.quit_testpmd()
> + self.dut.send_expect("killall -s INT qemu-system-x86_64",
> + "#")
> +
> + def tear_down(self):
> + """
> + Run after each test case.
> + """
> + self.dut.send_expect("killall -s INT testpmd", "#")
> + self.dut.send_expect("killall -s INT qemu-system-x86_64", "#")
> + self.dut.send_expect("rm -rf ./vhost-net", "#")
> + time.sleep(2)
> + self.dut.send_expect("ip netns del ns1", "# ", 30)
> + self.dut.send_expect(
> + "./usertools/dpdk-devbind.py -u %s" % (self.peer_pci), '# ', 30)
> + self.dut.send_expect(
> + "./usertools/dpdk-devbind.py -b %s %s" %
> + (self.pci_drv, self.peer_pci), '# ', 30)
> +
> + def tear_down_all(self):
> + """
> + Run after each test suite.
> + """
> + self.unprepare_dpdk()
> + self.dut.send_expect("ip netns del ns1", "# ", 30)
> + self.dut.send_expect(
> + "./usertools/dpdk-devbind.py -u %s" % (self.pci), '# ', 30)
> + self.dut.send_expect(
> + "./usertools/dpdk-devbind.py -b %s %s" %
> + (self.pci_drv, self.pci), '# ', 30)
> --
> 2.7.4
next prev parent reply other threads:[~2019-07-10 6:21 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-03 21:42 [dts] [PATCH V1 1/2][vhost gro] conf: add conf file for gro and gso lihong
2019-07-03 21:42 ` [dts] [PATCH V1 2/2][vhost gro] tests: add testsuite vhost gro lihong
2019-07-04 6:02 ` Wang, Yinan
2019-07-04 6:37 ` Ma, LihongX
2019-07-10 5:54 ` Tu, Lijuan
2019-07-10 6:21 ` Ma, LihongX [this message]
2019-07-04 6:03 ` [dts] [PATCH V1 1/2][vhost gro] conf: add conf file for gro and gso Wang, Yinan
2019-07-04 6:37 ` Ma, LihongX
2019-07-10 6:05 ` Tu, Lijuan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BE1E572D0441E34284F1F8B7AC28F1970BADDABB@SHSMSX101.ccr.corp.intel.com \
--to=lihongx.ma@intel.com \
--cc=dts@dpdk.org \
--cc=lijuan.tu@intel.com \
--cc=yinan.wang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).