[dts] [PATCH V3 2/3] add test suite for performance thread

Tu, Lijuan lijuan.tu at intel.com
Fri Oct 19 04:54:59 CEST 2018


test_perf_one_lcore_per_pcore / test_perf_n_lcore_per_pcore
I think the 2 cases is only different between 1 and N, but I get your argument are different, one is using coremask, and the other using lcore.

More comments inline.

> -----Original Message-----
> From: Wang, FeiX Y
> Sent: Thursday, October 18, 2018 11:39 PM
> To: dts at dpdk.org
> Cc: Tu, Lijuan <lijuan.tu at intel.com>; Wang, FeiX Y <feix.y.wang at intel.com>
> Subject: [dts] [PATCH V3 2/3] add test suite for performance thread
> 
> From: wang fei <feix.y.wang at intel.com>
> 
> Signed-off-by: wang fei <feix.y.wang at intel.com>
> ---
>  tests/TestSuite_performance_thread.py | 249
> ++++++++++++++++++++++++++
>  1 file changed, 249 insertions(+)
>  create mode 100644 tests/TestSuite_performance_thread.py
> 
> diff --git a/tests/TestSuite_performance_thread.py
> b/tests/TestSuite_performance_thread.py
> new file mode 100644
> index 0000000..b00e8a4
> --- /dev/null
> +++ b/tests/TestSuite_performance_thread.py
> @@ -0,0 +1,249 @@
> +# BSD LICENSE
> +#
> +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> +# 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.
> +Performance-Thread test script.
> +"""
> +
> +import utils
> +
> +from test_case import TestCase
> +from settings import HEADER_SIZE
> +from etgen import IxiaPacketGenerator
> +
> +class TestPerformanceThread(TestCase, IxiaPacketGenerator):
> +
> +    def set_up_all(self):
> +        self.ports = self.dut.get_ports()
> +        self.verify(len(self.ports) >= 2, "Insufficent Ports")
> +        self.socket = self.dut.get_numa_id(self.ports[0])
> +        self.port0_mac = self.dut.get_mac_address(self.ports[0])
> +        self.port1_mac = self.dut.get_mac_address(self.ports[1])
> +
> +
> + self.tester.extend_external_packet_generator(TestPerformanceThread,
> + self)
> +
> +        self.frame_sizes = [64, 128, 256, 512, 1024, 2000]
[Lijuan] I thinks frame size can be moved to configuration file.
> +        self.headers_size = HEADER_SIZE['eth'] + HEADER_SIZE['ip'] +
> HEADER_SIZE['tcp']
> +        self.nb_cores = self.get_suite_cfg()["cores"]
> +        self.path =
> "examples/performance-thread/l3fwd-thread/build/l3fwd-thread"
> +
> +        #results table header
> +        self.header = ["Cores", "Fsize", "Unidirectional MPPS", "Line
> + Rate(%)", "Bidirectional MPPS", "Line Rate(%)"]
> +
> +        # compile performance_thread app
> +        out =
> self.dut.build_dpdk_apps("./examples/performance-thread/l3fwd-thread")
> +        self.verify("Error" not in out, "compilation error 1")
> +        self.verify("No such file" not in out, "compilation error 2")
> +
> +    def set_up(self):
> +        pass
> +
> +    def test_perf_one_lcore_per_pcore(self):
> +        nb_cores = self.nb_cores
> +        params = "-n 2 -- -P -p 3 --enable-jumbo --max-pkt-len=2500
[Lijuan] Could you calculate the max-pkt-len, max(frame_sizes) + 200 is more reasonable.
"-n 2", the memory channel is configured in crb.cfg, so please utilize self.dut.get_memory_channels() to get the memory channels
> --no-lthread"
> +        test_data = {}
> +        for cores in nb_cores:
> +            _, core_mask = self.create_cores(cores)
> +            _,rx, tx = self.config_rx_tx(cores)
> +            app_cmdline = "{} -c {} {} --rx='{}' --tx='{}'".format(self.path,
> core_mask, params, rx, tx)
> +            self.dut.send_expect(app_cmdline, "", 15)
> +            test_data[cores] = self.start_traffic()
> +            self.dut.send_expect("^C", "# ", 15)
> +        self.print_result(test_data)
> +
> +    def test_perf_n_lthreads_per_pcore(self):
> +        nb_cores = self.nb_cores
> +        params = "-n 2 -- -P -p 3 --enable-jumbo --max-pkt-len=2500"
> +        test_data = {}
> +        for cores in nb_cores:
> +            _, core_mask = self.create_cores(cores)
> +            _,rx, tx = self.config_rx_tx(cores)
> +            app_cmdline = "{} -c {} {} --rx='{}' --tx='{}'".format(self.path,
> core_mask, params, rx, tx)
> +            self.dut.send_expect(app_cmdline, "", 15)
> +            test_data[cores] = self.start_traffic()
> +            self.dut.send_expect("^C", "# ", 15)
> +        self.print_result(test_data)
> +
> +    def test_perf_n_lcore_per_pcore(self):
> +        nb_cores = self.nb_cores
> +        params = "-- -P -p 3 --enable-jumbo --max-pkt-len 2500
> --no-lthread"
> +        test_data = {}
> +        for cores in nb_cores:
> +            _, core_mask = self.create_cores(cores)
> +            rxtx_config, rx, tx = self.config_rx_tx(cores)
> +            #app_cmdline = "{} -c {} -n 2 --lcores='{}' {} --rx='{}'
> --tx='{}'".format(self.path, core_mask, rxtx_config, params, rx, tx)
> +            app_cmdline = "{} -n 2 --lcores='{}' {} --rx='{}'
> --tx='{}'".format(self.path, rxtx_config, params, rx, tx)
[Lijuan] please remove your draft information
> +            self.dut.send_expect(app_cmdline, "", 15)
> +            test_data[cores] = self.start_traffic()
> +            self.dut.send_expect("^C", "# ", 15)
> +        self.print_result(test_data)
> +
> +    def create_cores(self, nb_cores):
> +        if nb_cores == 2:
> +            core_config = "1S/2C/1T"
> +        elif nb_cores == 4:
> +            core_config = "1S/4C/1T"
> +        elif nb_cores == 8:
> +            core_config = "1S/8C/1T"
> +        elif nb_cores == 16:
> +            core_config = "1S/16C/1T"
> +        core_list = self.dut.get_core_list(core_config, self.socket)
> +        core_mask = utils.create_mask(core_list)
> +        return core_list, core_mask
> +
> +    def config_rx_tx(self, cores):
> +        socket = self.socket
> +        ports = range(len(self.ports))
> +        tx_config = ""
> +        rx_config = ""
> +        core_mask = ""
> +        lcore_config = ""
> +        assert cores in self.nb_cores
> +
> +        #config --tx and --tx params for performace thread app
> +        if cores == 2:
> +            core_list, core_mask = self.create_cores(cores)
> +            lcore_config = "(%s-%s)@%s" % (core_list[0],core_list[-1],
> core_list[0])
> +            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
> +                 "({},{},{},{})".format(ports[1], 0, core_list[0], 0)
> +            tx = "({},{})".format(core_list[1], 0)
> +        elif cores == 4:
> +            core_list, core_mask = self.create_cores(cores)
> +            lcore_config = "(%s-%s)@%s" % (core_list[0], core_list[-1],
> core_list[0])
> +            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
> +                 "({},{},{},{})".format(ports[1], 0, core_list[1], 1)
> +            tx = "({},{})".format(core_list[2], 0) + "," + \
> +                 "({},{})".format(core_list[3], 1)
> +        elif cores == 8:
> +            core_list, core_mask = self.create_cores(cores)
> +            lcore_config = "(%s-%s)@%s" % (core_list[0], core_list[-1],
> core_list[0])
> +            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
> +                 "({},{},{},{})".format(ports[0], 1, core_list[1], 1) + "," +
> \
> +                 "({},{},{},{})".format(ports[1], 0, core_list[2], 2) + "," +
> \
> +                 "({},{},{},{})".format(ports[1], 1, core_list[3], 3)
> +            tx = "({},{})".format(core_list[4], 0) + "," +
> "({},{})".format(core_list[5], 1) + "," + \
> +                 "({},{})".format(core_list[6], 2) + "," +
> "({},{})".format(core_list[7], 3)
> +        elif cores == 16:
> +            core_list, core_mask = self.create_cores(cores)
> +            lcore_config = "(%s-%s)@%s" % (core_list[0], core_list[-1],
> core_list[0])
> +            rx = "({},{},{},{})".format(ports[0], 0, core_list[0], 0) + "," + \
> +                 "({},{},{},{})".format(ports[0], 1, core_list[1], 1) + "," +
> \
> +                 "({},{},{},{})".format(ports[0], 2, core_list[2], 2) + "," +
> \
> +                 "({},{},{},{})".format(ports[0], 3, core_list[3], 3) + "," +
> \
> +                 "({},{},{},{})".format(ports[1], 0, core_list[4], 4) + "," +
> \
> +                 "({},{},{},{})".format(ports[1], 1, core_list[5], 5) + "," +
> \
> +                 "({},{},{},{})".format(ports[1], 2, core_list[6], 6) + "," +
> \
> +                 "({},{},{},{})".format(ports[1], 3, core_list[7], 7)
> +            tx = "({},{})".format(core_list[8], 0) + "," +
> "({},{})".format(core_list[9], 1) + "," + \
> +                 "({},{})".format(core_list[10], 2) + "," +
> "({},{})".format(core_list[11], 3) + "," + \
> +                 "({},{})".format(core_list[12], 4) + "," +
> "({},{})".format(core_list[13], 5) + "," + \
> +                 "({},{})".format(core_list[14], 6) + "," +
> "({},{})".format(core_list[15], 7)
> +        return lcore_config, rx, tx
> +
> +    def start_traffic(self):
> +        frame_sizes = self.frame_sizes
> +        headers_size = self.headers_size
> +        ports = self.ports
> +        dmac0 = self.port0_mac
> +        dmac1 = self.port1_mac
> +
> +        tgen_input_unidirection = []
> +
> tgen_input_unidirection.append((self.tester.get_local_port(ports[0]),
> +                           self.tester.get_local_port(ports[1]),
> +                           "stream0.pcap"))
> +
> +        tgen_input_bidirection = []
> +
> tgen_input_bidirection.append((self.tester.get_local_port(ports[0]),
> +
> self.tester.get_local_port(ports[1]),
> +                                       "stream0.pcap"))
> +
> tgen_input_bidirection.append((self.tester.get_local_port(ports[1]),
> +
> self.tester.get_local_port(ports[0]),
> +                                       "stream1.pcap"))
> +
> +        result_data = {}
> +        for frame_size in frame_sizes:
> +            # create pcap file
> +            payload_size = frame_size - headers_size
> +            self.tester.scapy_append(
> +                'wrpcap("stream0.pcap",
> [Ether(src="52:00:00:00:00:00",dst="%s")/IP(src="1.2.3.4",dst="2.1.1.1")/TC
> P()/("X"*%d)])' %
> +                     (dmac0, payload_size))
> +            self.tester.scapy_execute()
> +            self.logger.info("Starting Uni-Direction Traffic For Frame
> Size: %s" % frame_size)
> +            _, pps =
> self.tester.traffic_generator_throughput(tgen_input_unidirection,
> rate_percent=100, delay=20)
> +            mpps = pps / 1000000.0
> +            self.verify( mpps != 0, "Traffic Blocked")
> +            wirespeed = self.wirespeed(self.nic, frame_size, 1)
> +            rate = (mpps / wirespeed) * 100
> +            result_data[frame_size] = [mpps, rate]
> +
> +            self.logger.info("Starting Bi-direction Traffic For Frame
> Size: %s" % frame_size)
> +            self.tester.scapy_append(
> +                'wrpcap("stream1.pcap",
> [Ether(src="52:00:00:00:00:00",dst="%s")/IP(src="1.2.3.4",dst="1.1.1.1")/TC
> P()/("X"*%d)])' % (
> +                   dmac1, payload_size))
> +            self.tester.scapy_execute()
> +            _, pps =
> self.tester.traffic_generator_throughput(tgen_input_bidirection,
> rate_percent=100, delay=20)
> +            mpps = pps / 1000000.0
> +            self.verify( mpps != 0, "Traffic Blocked")
> +            wirespeed = self.wirespeed(self.nic, frame_size, 2)
> +            rate = (mpps / wirespeed) * 100
> +            result_data[frame_size].extend([mpps, rate])
> +
> +        return result_data
> +
> +    def print_result(self, data):
> +        '''
> +        print test result table
> +        '''
> +        header = self.header
> +        frame_sizes = self.frame_sizes
> +        nb_cores = self.nb_cores
> +
> +        self.result_table_create(header)
> +        try:
> +            for nb_core in nb_cores:
> +                for frame_size in frame_sizes:
> +                    row = [nb_core, frame_size]
> +                    row.extend(data[nb_core][frame_size])
> +                    self.result_table_add(row)
> +            self.result_table_print()
> +        except:
> +            raise
> +
> +    def tear_down(self):
> +        pass
> +
> +    def tear_down_all(self):
> +        pass
> +
> --
> 2.17.1



More information about the dts mailing list