From patchwork Fri Mar 10 07:52:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ling, WeiX" X-Patchwork-Id: 124932 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 1A96441E3A; Fri, 10 Mar 2023 08:53:05 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 155CF4111C; Fri, 10 Mar 2023 08:53:05 +0100 (CET) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id DE83D40150 for ; Fri, 10 Mar 2023 08:53:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1678434783; x=1709970783; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=/S780Xmwn1y/AbGtaYq2LimhGH0GPmn8m4K1vc2oWSc=; b=OF9hAhjyM//AKv2X1sSRgD+uYAtsGzYmK0u4iXUDzSSJ1eUmQI9G3G/O Pb7I3iaQ/anvgRLopRT8xhUX6fXXUMpr6Dxbmp5sZ4VKo867+Mo2WLjPa GxCYEovTWyCjNQG2CkRi9MsqhJCF8ZkYdUTOwbfvUzlJlv7G/1dzqqA+n SMZRz1yPVADCN/Nem2mYL7tOLN2+5b/+wLypXgzGa55zjjJ4IR72C+3bK 7HhmhiUTJV3fEkB5sNxzUr5kIRpg9+UAklSvqWSKLzf5u8cnWpP7+n8QH vGEHuyEpfaF0nxT2v8SiAppWIsBdqDR70zZ/lbtdFR0g1GGPjOqFROAzX w==; X-IronPort-AV: E=McAfee;i="6500,9779,10644"; a="339034542" X-IronPort-AV: E=Sophos;i="5.98,249,1673942400"; d="scan'208";a="339034542" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2023 23:53:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10644"; a="677711136" X-IronPort-AV: E=Sophos;i="5.98,249,1673942400"; d="scan'208";a="677711136" Received: from unknown (HELO localhost.localdomain) ([10.239.252.222]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Mar 2023 23:53:00 -0800 From: Wei Ling To: dts@dpdk.org Cc: Wei Ling Subject: [dts][PATCH V2 3/3] tests/dsa: add dsa testsuite Date: Fri, 10 Mar 2023 15:52:31 +0800 Message-Id: <20230310075231.1462919-1-weix.ling@intel.com> X-Mailer: git-send-email 2.25.1 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 Add new dsa testsuite to test dpdk-dma application and example of how to use the DMAdev API to make a packet copy application use DSA channel with DPDK driver and Kernel driver. Signed-off-by: Wei Ling --- tests/TestSuite_dsa.py | 485 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 tests/TestSuite_dsa.py diff --git a/tests/TestSuite_dsa.py b/tests/TestSuite_dsa.py new file mode 100644 index 00000000..1291dc68 --- /dev/null +++ b/tests/TestSuite_dsa.py @@ -0,0 +1,485 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation +# + +import re +import time + +from framework.packet import Packet +from framework.pktgen import TRANSMIT_CONT +from framework.test_case import TestCase + +from .virtio_common import dsa_common as DC + + +class TestDSA(TestCase): + def set_up_all(self): + """ + Run at the start of each test suite. + """ + self.frame_sizes = [64, 256, 512, 1024, 1518] + self.dut_ports = self.dut.get_ports() + self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing") + self.ports_socket = self.dut.get_numa_id(self.dut_ports[0]) + out = self.dut.build_dpdk_apps("./examples/dma") + self.verify("Error" not in out, "compilation dma error") + self.dma_path = self.dut.apps_name["dma"] + self.dma_name = self.dma_path.split("/")[-1] + self.core_num = 1 + self.DC = DC(self) + + def set_up(self): + """ + Run before each test case. + """ + # Prepare the result table + self.table_header = ["Frame"] + self.table_header.append("Mpps") + self.table_header.append("Worker Threads") + self.table_header.append("Copy Mode") + self.table_header.append("Updating MAC") + self.table_header.append("Rx Queues") + self.table_header.append("% linerate") + self.result_table_create(self.table_header) + self.dut.send_expect("killall -I %s" % self.dma_name, "#", 20) + self.DC.reset_all_work_queue() + self.DC.bind_all_dsa_to_kernel() + + def get_core_list(self): + """ + get cores list depend on self.work_thread + """ + core_config = "1S/%dC/1T" % self.core_num + core_list = self.dut.get_core_list(core_config, socket=self.ports_socket) + return core_list + + def launch_dma_app(self, eal_params): + """ + launch dma with different params + """ + port_info = 0 + for i in range(self.nic_port_num): + port_info |= 1 << i + updating_mac = ( + "--mac-updating" if self.updating_mac == "enabled" else "--no-mac-updating" + ) + rx_queues = self.rx_queues / self.nic_port_num + cmd = "%s %s -- -p %s -q %d %s -c %s" % ( + self.dma_path, + eal_params, + hex(port_info), + rx_queues, + updating_mac, + self.copy_mode, + ) + expected = self.dma_path.split("/")[-1].strip() + self.dut.send_expect(cmd, expected) + time.sleep(3) + out = self.dut.get_session_output(timeout=1) + self.logger.info("out before: {}".format(out)) + """ + when start DSA app, default cores num is 2, it will only one thread + when the cores num > 2, there will have 2 thread, and the max value of thread + num is 2. + """ + self.work_thread = 2 if self.core_num > 2 else 1 + work_thread_info = "Worker Threads = %d" % self.work_thread + copy_mode_info = "Copy Mode = %s" % self.copy_mode + update_mac_info = "Updating MAC = %s" % self.updating_mac + rx_queues_info = "Rx Queues = %d" % rx_queues + self.verify( + work_thread_info in out + and copy_mode_info in out + and update_mac_info in out + and rx_queues_info in out, + "The output info not match setting for the cmd, please check", + ) + + def config_stream(self, frame_size): + stream_ids = [] + for port in range(self.nic_port_num): + tx_port = self.tester.get_local_port(self.dut_ports[port]) + rx_port = tx_port + if self.nic_port_num > 1: + if port % self.nic_port_num == 0: + rx_port = self.tester.get_local_port(self.dut_ports[port + 1]) + else: + rx_port = self.tester.get_local_port(self.dut_ports[port - 1]) + dst_mac = self.dut.get_mac_address(self.dut_ports[port]) + # pkt config + pkt = Packet(pkt_type="UDP", pkt_len=frame_size) + # pkt.config_layer("ether", {"dst": "%s" % dst_mac}) + pkt.config_layer("udp", {"src": 1111, "dst": 1112}) + pkt.save_pcapfile( + self.tester, "%s/dsa_%d.pcap" % (self.tester.tmp_file, port) + ) + stream_option = { + "pcap": "%s/dsa_%d.pcap" % (self.tester.tmp_file, port), + "fields_config": { + "ether": { + "dst": { + "action": "random", + } + }, + "ip": { + "src": { + "action": "random", + "start": "16.0.0.1", + "step": 1, + "end": "16.0.0.64", + } + }, + }, + "stream_config": { + "rate": 100, + "transmit_mode": TRANSMIT_CONT, + }, + } + stream_id = self.tester.pktgen.add_stream( + tx_port, tx_port, "%s/dsa_%d.pcap" % (self.tester.tmp_file, port) + ) + self.tester.pktgen.config_stream(stream_id, stream_option) + stream_ids.append(stream_id) + return stream_ids + + def send_and_verify(self, check_each_queue=True): + """ + Send packet with packet generator and verify + """ + for frame_size in self.frame_sizes: + self.tester.pktgen.clear_streams() + stream_ids = self.config_stream(frame_size) + traffic_opt = {"method": "throughput", "rate": 100, "duration": 20} + self.logger.info( + "start to send %d frame size packets from pktgen" % frame_size + ) + _, pps = self.tester.pktgen.measure(stream_ids, traffic_opt) + self.verify( + pps > 0, + "%s can not receive packets of frame size %d" + % (self.running_case, frame_size), + ) + self.update_result_tables(frame_size, pps) + if check_each_queue: + self.check_enqueue_packets_of_each_channel() + + def check_enqueue_packets_of_each_channel(self): + """ + Check stats of dma app, each dma channel can enqueue packets + """ + out = self.dut.get_session_output(timeout=2) + index = out.rfind("Statistics for port 0") + out = out[index:] + data_info = re.findall("Total completed ops:\s*(\d*)", out) + self.verify( + (len(data_info) - 1) == self.rx_queues, + "There miss some queue, the run queue is " + "%d, and expect queue num is %d" % ((len(data_info) - 1), self.rx_queues), + ) + for index in range(self.rx_queues): + self.verify( + data_info[index] != 0, "the queue %d can not enqueues data" % index + ) + + def update_result_tables(self, frame_size, pps): + Mpps = pps / 1000000.0 + linerate = ( + Mpps * 100 / float(self.wirespeed(self.nic, frame_size, self.nic_port_num)) + ) + self.work_thread = 2 if self.core_num > 2 else 1 + results_row = [frame_size] + results_row.append(Mpps) + results_row.append(self.work_thread) + results_row.append(self.copy_mode) + results_row.append(self.updating_mac) + results_row.append(self.rx_queues / self.nic_port_num) + results_row.append(linerate) + self.result_table_add(results_row) + + def test_perf_dsa_basic_test_using_dpdk_driver(self): + """ + Test Case 1: DMA basic test with differnet size packets using DSA dpdk driver + """ + self.used_dsa = self.DC.bind_dsa_to_dpdk( + dsa_number=1, driver_name="vfio-pci", socket=self.ports_socket + ) + self.core_num = 2 + self.rx_queues = 1 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "hw" + ports = self.used_dsa + for i in range(self.nic_port_num): + ports.append(self.dut.ports_info[i]["pci"]) + port_options = {self.used_dsa[0]: "max_queues=%s" % self.rx_queues} + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports, port_options=port_options + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_multi_threads_using_dpdk_driver(self): + """ + Test Case 2: DMA test with multi-threads using DSA dpdk driver + """ + self.used_dsa = self.DC.bind_dsa_to_dpdk( + dsa_number=1, driver_name="vfio-pci", socket=self.ports_socket + ) + self.core_num = 3 + self.rx_queues = 1 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "hw" + ports = self.used_dsa + for i in range(self.nic_port_num): + ports.append(self.dut.ports_info[i]["pci"]) + port_options = {self.used_dsa[0]: "max_queues=%s" % self.rx_queues} + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports, port_options=port_options + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_multi_nic_ports_using_dpdk_driver(self): + """ + Test Case 3: DMA test with multi nic ports using DSA dpdk driver + """ + self.verify(len(self.dut_ports) >= 2, "Insufficient ports for testing") + self.used_dsa = self.DC.bind_dsa_to_dpdk( + dsa_number=1, driver_name="vfio-pci", socket=self.ports_socket + ) + self.core_num = 5 + self.rx_queues = 2 + self.nic_port_num = 2 + self.updating_mac = "enabled" + self.copy_mode = "hw" + ports = self.used_dsa + for i in range(self.nic_port_num): + ports.append(self.dut.ports_info[i]["pci"]) + port_options = {self.used_dsa[0]: "max_queues=%s" % self.rx_queues} + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports, port_options=port_options + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_multi_queues_using_dpdk_driver(self): + """ + Test Case 4: DMA test with multi-queues using DSA dpdk driver + """ + self.used_dsa = self.DC.bind_dsa_to_dpdk( + dsa_number=1, driver_name="vfio-pci", socket=self.ports_socket + ) + self.core_num = 3 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "hw" + queue_list = [2, 4, 8] + ports = self.used_dsa + for i in range(self.nic_port_num): + ports.append(self.dut.ports_info[i]["pci"]) + for self.rx_queues in queue_list: + port_options = {self.used_dsa[0]: "max_queues=%s" % self.rx_queues} + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports, port_options=port_options + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.dut.send_expect("^c", "# ") + self.result_table_print() + + def test_perf_dsa_with_diff_update_mac_using_dpdk_driver(self): + """ + Test Case 5: DMA performance comparison between mac-updating and no-mac-updating using DSA dpdk driver + """ + self.used_dsa = self.DC.bind_dsa_to_dpdk( + dsa_number=1, driver_name="vfio-pci", socket=self.ports_socket + ) + self.core_num = 2 + self.rx_queues = 2 + self.nic_port_num = 1 + self.updating_mac = "disabled" + self.copy_mode = "hw" + ports = self.used_dsa + for i in range(self.nic_port_num): + ports.append(self.dut.ports_info[i]["pci"]) + port_options = {self.used_dsa[0]: "max_queues=%s" % self.rx_queues} + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports, port_options=port_options + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + + self.dut.send_expect("^c", "# ") + self.updating_mac = "enabled" + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_diff_copy_mode_using_dpdk_driver(self): + """ + Test Case 6: DMA performance comparison between SW copies and HW copies using DSA dpdk driver + """ + self.used_dsa = self.DC.bind_dsa_to_dpdk( + dsa_number=1, driver_name="vfio-pci", socket=self.ports_socket + ) + self.core_num = 3 + self.rx_queues = 4 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "sw" + ports = self.used_dsa + for i in range(self.nic_port_num): + ports.append(self.dut.ports_info[i]["pci"]) + port_options = {self.used_dsa[0]: "max_queues=%s" % self.rx_queues} + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports, port_options=port_options + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=False) + + self.dut.send_expect("^c", "# ") + self.copy_mode = "hw" + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_basic_test_using_kernel_driver(self): + """ + Test Case 7: DMA basic test with differnet size packets using DSA kernel driver + """ + self.DC.create_work_queue(work_queue_number=1, dsa_index=0) + self.core_num = 2 + self.rx_queues = 1 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "hw" + ports = [self.dut.ports_info[0]["pci"]] + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_multi_thread_using_kernel_driver(self): + """ + Test Case 8: DMA test with multi-threads using DSA kernel driver + """ + self.DC.create_work_queue(work_queue_number=1, dsa_index=0) + self.core_num = 3 + self.rx_queues = 1 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "hw" + ports = [self.dut.ports_info[0]["pci"]] + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_multi_nic_ports_using_kernle_driver(self): + """ + Test Case 9: DMA test with multi nic ports using DSA kernel driver + """ + self.verify(len(self.dut_ports) >= 2, "Insufficient ports for testing") + self.DC.create_work_queue(work_queue_number=2, dsa_index=0) + self.core_num = 5 + self.rx_queues = 2 + self.nic_port_num = 2 + self.updating_mac = "enabled" + self.copy_mode = "hw" + ports = [self.dut.ports_info[0]["pci"], self.dut.ports_info[1]["pci"]] + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_multi_queues_using_kernel_driver(self): + """ + Test Case 10: DMA test with multi-queues using DSA kernel driver + """ + self.DC.create_work_queue(work_queue_number=8, dsa_index=0) + self.core_num = 3 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "hw" + queue_list = [2, 4, 8] + for self.rx_queues in queue_list: + ports = [self.dut.ports_info[0]["pci"]] + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.dut.send_expect("^c", "# ") + self.result_table_print() + + def test_perf_dsa_with_diff_update_mac_using_kernel_driver(self): + """ + Test Case 11: DMA performance comparison between mac-updating and no-mac-updating using DSA kernel driver + """ + self.DC.create_work_queue(work_queue_number=2, dsa_index=0) + self.core_num = 2 + self.rx_queues = 2 + self.nic_port_num = 1 + self.updating_mac = "disabled" + self.copy_mode = "hw" + ports = [self.dut.ports_info[0]["pci"]] + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + + self.dut.send_expect("^c", "# ") + self.updating_mac = "enabled" + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def test_perf_dsa_with_diff_copy_mode_using_kernel_driver(self): + """ + Test Case 12: DMA performance comparison between SW copies and HW copies using DSA kernel driver + """ + self.DC.create_work_queue(work_queue_number=4, dsa_index=0) + self.core_num = 3 + self.rx_queues = 4 + self.nic_port_num = 1 + self.updating_mac = "enabled" + self.copy_mode = "sw" + ports = [self.dut.ports_info[0]["pci"]] + eal_params = self.dut.create_eal_parameters( + cores=self.get_core_list(), ports=ports + ) + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=False) + + self.dut.send_expect("^c", "# ") + self.copy_mode = "hw" + self.launch_dma_app(eal_params=eal_params) + self.send_and_verify(check_each_queue=True) + self.result_table_print() + + def tear_down(self): + """ + Run after each test case. + """ + self.dut.send_expect("^c", "# ") + self.dut.send_expect("killall -I %s" % self.dma_name, "#", 20) + self.dut.kill_all() + self.DC.reset_all_work_queue() + self.DC.bind_all_dsa_to_kernel() + + def tear_down_all(self): + """ + Run after each test suite. + """ + pass