[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