From patchwork Sun Jul 16 14:00:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yaqi Tang X-Patchwork-Id: 129561 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 41ABB42E8D; Sun, 16 Jul 2023 16:01:57 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3CBD342BAC; Sun, 16 Jul 2023 16:01:57 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mails.dpdk.org (Postfix) with ESMTP id 241F642BAC for ; Sun, 16 Jul 2023 16:01:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689516115; x=1721052115; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nlsUr2ARcN1g9gM9KdwjxS+2Vqd3u4Iv7W4AkHD7+AE=; b=Do5ZjwDDBsHugjVhTMXEommpWcybzHkIX/QbetOwTFttIkRK2kfpZAIL oIYlPA5J7pzQbPwM/x1ZgkETwFgXi5ef0/V1wSgsqx4kfCAkjCXbBcM8y 9vWytvAjdTxFFeS0XI/9A0JVVRFkHww7fBERpeDqJBlTp+1nGRkH7Xsef 039mZHcPch2tozz+43OQ4ZPWpuowRV1/b6197SXgJe8WMz9JXNwxzviH1 4u+5t9CVZUdL/kqxT62awZ0+21nPJB/3enWhnsfS652H+v+BOOZhrgBqW /rvLOoorg4zny4kMKeUiF4XvTHjSRalpj1stXPq9+eqvaoM6R5ba/ngIF A==; X-IronPort-AV: E=McAfee;i="6600,9927,10773"; a="345351256" X-IronPort-AV: E=Sophos;i="6.01,210,1684825200"; d="scan'208";a="345351256" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2023 07:01:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10773"; a="896930531" X-IronPort-AV: E=Sophos;i="6.01,210,1684825200"; d="scan'208";a="896930531" Received: from dpdk-yaqi.sh.intel.com ([10.67.118.189]) by orsmga005.jf.intel.com with ESMTP; 16 Jul 2023 07:01:52 -0700 From: Yaqi Tang To: dts@dpdk.org Cc: Yaqi Tang Subject: [PATCH V1 3/3] tests/igc_tx_timestamp: igc enable tx timestamp offloading Date: Sun, 16 Jul 2023 14:00:54 +0000 Message-Id: <20230716140054.3222247-4-yaqi.tang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230716140054.3222247-1-yaqi.tang@intel.com> References: <20230716140054.3222247-1-yaqi.tang@intel.com> 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 IGC Enable Tx timestamp offloading by leveraging I225 NIC's "Launch Time". Signed-off-by: Yaqi Tang --- tests/TestSuite_igc_tx_timestamp.py | 184 ++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 tests/TestSuite_igc_tx_timestamp.py diff --git a/tests/TestSuite_igc_tx_timestamp.py b/tests/TestSuite_igc_tx_timestamp.py new file mode 100644 index 00000000..5fa0ee32 --- /dev/null +++ b/tests/TestSuite_igc_tx_timestamp.py @@ -0,0 +1,184 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation +# + +import re +import time + +from framework.pmd_output import PmdOutput +from framework.test_case import TestCase +from framework.utils import GREEN, RED + + +class TimestampTest(TestCase): + def set_up_all(self): + """ + Run at the start of each test suite. + Generic filter Prerequistites + """ + self.verify( + self.nic in ["IGC-I225_LM", "IGC-I226_LM"], + "%s nic not support tx timestamp" % self.nic, + ) + self.dut_ports = self.dut.get_ports(self.nic) + self.ports_socket = self.dut.get_numa_id(self.dut_ports[0]) + # Verify that enough ports are available + self.verify(len(self.dut_ports) >= 1, "Insufficient ports") + self.tester_port0 = self.tester.get_local_port(self.dut_ports[0]) + self.tester_iface0 = self.tester.get_interface(self.tester_port0) + self.pmdout = PmdOutput(self.dut) + self.pf_pci = self.dut.ports_info[self.dut_ports[0]]["pci"] + + apps_name = "test-timestamp" + self.build_test_app(apps_name) + + def set_up(self): + """ + Run before each test case. + """ + pass + + def build_test_app(self, apps_name): + # Compile test app + print(self.tester.send_expect("ls", "#", 5)) + test_rx_timestamp = "/root/pkt_rx_tx.c" + out = self.tester.send_expect( + "gcc %s -o %s -lpthread" % (test_rx_timestamp, apps_name), "#", 15 + ) + self.verify("Error" not in out, "Compilation %s error" % apps_name) + output = self.tester.send_expect("find -name %s" % apps_name, "#") + self.verify("%s" % apps_name in output, "Compilation %s error" % apps_name) + + def launch_testpmd(self, param, intra): + """ + start testpmd + """ + # Prepare testpmd EAL and parameters + self.pmdout.start_testpmd( + param=param, + eal_param=f"-a {self.pf_pci}", + socket=self.ports_socket, + ) + # Test link status + res = self.pmdout.wait_link_status_up("all", 5) + self.verify(res is True, "there have port link is down") + self.pmdout.execute_cmd("set fwd txonly") + self.pmdout.execute_cmd("set txtimes 30000000,%d" % intra) + self.pmdout.execute_cmd("start", "testpmd>", 5) + self.pmdout.execute_cmd("stop") + + def launch_test_app(self, apps_name): + print(self.tester.send_expect("ls", "#", 5)) + self.tester.send_command("./%s -i %s -t" % (apps_name, self.tester_iface0), "#") + out = self.tester.get_session_output(timeout=0.1) + self.verify("Press Enter to continue" in out, "Launch test app failed.") + + def check_time_interval_error(self, interval): + out = self.tester.get_session_output(timeout=0.1) + rx_ts_pat = ".*ts\s+(\d+)" + rx_ts = re.findall(rx_ts_pat, out, re.M) + rx_ts = list(map(int, rx_ts)) + self.error_msgs = [] + intervals = [] + if len(rx_ts) != 32: + error_msg = "Tester should recieve 32 RX timestamps." + self.logger.error(error_msg) + self.error_msgs.append(error_msg) + else: + for i in range(len(rx_ts) - 1): + rx = rx_ts[i + 1] - rx_ts[i] + intervals.append(rx) + self.logger.info("Rx time intervals: {}".format(intervals)) + error = [abs((x - interval) / interval) * 100 for x in intervals] + error = [round(x, 2) for x in error] + self.logger.info("Rx time interval error: {}".format(error)) + if all(x < 50 for x in error) == False: + error_msg = "The time interval error for Rx timestamp is too large." + self.logger.error(error_msg) + self.error_msgs.append(error_msg) + else: + self.logger.info( + "max_error={}%, min_error={}%".format(max(error), min(error)) + ) + self.verify(not self.error_msgs, "some subcases failed") + + def handle_tx_timestamp_case(self, apps_name, param, intra, interval): + self.launch_test_app(apps_name) + self.launch_testpmd(param, intra) + self.check_time_interval_error(interval) + self.pmdout.execute_cmd("quit", "#") + + def test_with_tx_timestamp_check_time_interval(self, apps_name="test-timestamp"): + # Subcase 1: set txtimes intra 2000ns, check the time interval of Rx timestamp is 2000ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 1: set txtimes intra 2000ns ================" + ) + self.handle_tx_timestamp_case( + apps_name, param="--tx-offloads=0x200000", intra=2000, interval=2000 + ) + + # Subcase 2: set txtimes intra 1000ns, check the time interval of Rx timestamp is 1000ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 2: set txtimes intra 1000ns ================" + ) + self.handle_tx_timestamp_case( + apps_name, param="--tx-offloads=0x200000", intra=1000, interval=1000 + ) + + # Subcase 3: set txtimes intra 400ns, check the time interval of Rx timestamp is 400ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 3: set txtimes intra 400ns ================" + ) + self.handle_tx_timestamp_case( + apps_name, param="--tx-offloads=0x200000", intra=400, interval=400 + ) + + # Subcase 4: set txtimes intra 300ns, check the time interval of Rx timestamp is 300ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 4: set txtimes intra 300ns ================" + ) + self.handle_tx_timestamp_case( + apps_name, param="--tx-offloads=0x200000", intra=300, interval=300 + ) + + # Subcase 5: set txtimes intra 200ns, check the time interval of Rx timestamp is 300ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 5: set txtimes intra 200ns ================" + ) + self.handle_tx_timestamp_case( + apps_name, param="--tx-offloads=0x200000", intra=200, interval=300 + ) + + def test_without_tx_timestamp_check_time_interval(self, apps_name="test-timestamp"): + # Subcase 1: set txtimes intra 2000ns, check the time interval of Rx timestamp is 300ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 1: set txtimes intra 2000ns ================" + ) + self.handle_tx_timestamp_case(apps_name, param="", intra=2000, interval=300) + + # Subcase 2: set txtimes intra 1000ns, check the time interval of Rx timestamp is 300ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 2: set txtimes intra 1000ns ================" + ) + self.handle_tx_timestamp_case(apps_name, param="", intra=1000, interval=300) + + # Subcase 3: set txtimes intra 400ns, check the time interval of Rx timestamp is 300ns and measure MAX/MIN error. + self.logger.info( + "===================Test subcase 3: set txtimes intra 400ns ================" + ) + self.handle_tx_timestamp_case(apps_name, param="", intra=400, interval=300) + + def tear_down(self): + """ + Run after each test case. + """ + # Bind the interfaces to the igc driver, then bind to the vfio-pci driver. + self.pmdout.execute_cmd("quit", "#") + self.dut.bind_interfaces_linux("igc") + self.dut.bind_interfaces_linux("vfio-pci") + + def tear_down_all(self): + """ + Run after each test suite. + """ + self.dut.kill_all()