test suite reviews and discussions
 help / color / mirror / Atom feed
From: Haiyang Zhao <haiyangx.zhao@intel.com>
To: dts@dpdk.org
Cc: Haiyang Zhao <haiyangx.zhao@intel.com>
Subject: [dts] [PATCH V1 3/3] tests: add runtime_vf_queue_number_maxinum
Date: Sat, 12 Oct 2019 17:57:21 +0800	[thread overview]
Message-ID: <1570874241-92780-3-git-send-email-haiyangx.zhao@intel.com> (raw)
In-Reply-To: <1570874241-92780-1-git-send-email-haiyangx.zhao@intel.com>

*.add new test suite runtime_vf_queue_number_maxinum.

Signed-off-by: Haiyang Zhao <haiyangx.zhao@intel.com>
---
 tests/TestSuite_runtime_vf_queue_number_maxinum.py | 301 +++++++++++++++++++++
 1 file changed, 301 insertions(+)
 create mode 100644 tests/TestSuite_runtime_vf_queue_number_maxinum.py

diff --git a/tests/TestSuite_runtime_vf_queue_number_maxinum.py b/tests/TestSuite_runtime_vf_queue_number_maxinum.py
new file mode 100644
index 0000000..ae41944
--- /dev/null
+++ b/tests/TestSuite_runtime_vf_queue_number_maxinum.py
@@ -0,0 +1,301 @@
+# BSD LICENSE
+#
+# Copyright(c) <2019> 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.
+
+'''
+
+import time
+import re
+import math
+from test_case import TestCase
+from pmd_output import PmdOutput
+
+
+class TestRuntimeVfQnMaxinum(TestCase):
+    supported_vf_driver = ['igb_uio', 'vfio-pci']
+    rss_key = '6EA6A420D5138E712433B813AE45B3C4BECB2B405F31AD6C331835372D15E2D5E49566EE0ED1962AFA1B7932F3549520FD71C75E'
+    max_white_per_testpmd = 18
+
+    def set_up_all(self):
+        self.verify(self.nic in ["fortville_eagle", "fortville_spirit", "fortville_25g", "fortpark_TLV"],
+                    "Only supported by Fortville")
+        self.dut_ports = self.dut.get_ports(self.nic)
+        self.verify(len(self.dut_ports) >= 1, 'Insufficient ports')
+        self.src_intf = self.tester.get_interface(self.tester.get_local_port(0))
+        self.src_mac = self.tester.get_mac(self.tester.get_local_port(0))
+        self.dst_mac = self.dut.get_mac_address(0)
+        self.pf_pci = self.dut.ports_info[self.dut_ports[0]]['pci']
+        self.used_dut_port = self.dut_ports[0]
+        self.pmdout = PmdOutput(self.dut)
+        self.setup_test_env('igb_uio')
+
+    def set_up(self):
+        """
+        Run before each test case.
+        """
+        pass
+
+    def setup_test_env(self, driver='default'):
+        """
+        Bind fortville nic to DPDK PF, and create 32/64 vfs on it.
+        Start testpmd based on the created vfs.
+        """
+        if self.nic in ['fortville_eagle']:
+            self.dut.generate_sriov_vfs_by_port(self.used_dut_port, 32, driver=driver)
+        elif self.nic in ['fortville_25g', 'fortville_spirit', 'fortpark_TLV']:
+            self.dut.generate_sriov_vfs_by_port(self.used_dut_port, 64, driver=driver)
+
+        self.sriov_vfs_port_0 = self.dut.ports_info[self.used_dut_port]['vfs_port']
+
+        # set vf assign method and vf driver
+        self.vf_driver = self.get_suite_cfg()['vf_driver']
+        if self.vf_driver is None:
+            self.vf_driver = 'vfio-pci'
+        self.verify(self.vf_driver in self.supported_vf_driver, "Unspported vf driver")
+
+        for port in self.sriov_vfs_port_0:
+            port.bind_driver(self.vf_driver)
+        self.vf1_session = self.dut.new_session()
+        self.vf2_session = self.dut.new_session()
+        self.pf_pmdout = PmdOutput(self.dut)
+        self.vf1_pmdout = PmdOutput(self.dut, self.vf1_session)
+        self.vf2_pmdout = PmdOutput(self.dut, self.vf2_session)
+
+    def destroy_test_env(self):
+        if getattr(self, 'pf_pmdout', None):
+            self.pf_pmdout.execute_cmd('quit', '# ')
+            self.pf_pmdout = None
+
+        if getattr(self, 'vf1_pmdout', None):
+            self.vf1_pmdout.execute_cmd('quit', '# ', timeout=200)
+            self.vf1_pmdout = None
+        if getattr(self, 'vf1_session', None):
+            self.dut.close_session(self.vf1_session)
+
+        if getattr(self, 'vf2_pmdout', None):
+            self.vf2_pmdout.execute_cmd('quit', '# ')
+            self.vf2_pmdout = None
+        if getattr(self, 'vf2_session', None):
+            self.dut.close_session(self.vf2_session)
+
+        if getattr(self, 'vf3_pmdout', None):
+            self.vf3_pmdout.execute_cmd('quit', '# ', timeout=150)
+            self.vf3_pmdout = None
+        if getattr(self, 'vf3_session', None):
+            self.dut.close_session(self.vf3_session)
+
+        # reset used port's sriov
+        if getattr(self, 'used_dut_port', None):
+            self.dut.destroy_sriov_vfs_by_port(self.used_dut_port)
+            port = self.dut.ports_info[self.used_dut_port]['port']
+            port.bind_driver()
+            self.used_dut_port = None
+
+    def send_packet(self, dest_mac, itf, count):
+        """
+        Sends packets.
+        """
+        self.tester.scapy_foreground()
+        time.sleep(2)
+        for i in range(count):
+            quotient = i // 254
+            remainder = i % 254
+            packet = r'sendp([Ether(dst="{0}", src=get_if_hwaddr("{1}"))/IP(src="10.0.{2}.{3}", ' \
+                     r'dst="192.168.{2}.{3}")],iface="{4}")'.format(dest_mac, itf, quotient, remainder + 1, itf)
+            self.tester.scapy_append(packet)
+        self.tester.scapy_execute()
+        time.sleep(2)
+
+    def test_vf_consume_max_queues_on_one_pf(self):
+        """
+        Test case 1: VF consume max queue number on one PF port.
+        For four port fortville nic, each port has 384 queues,
+        and for two port fortville nic, each port has 768 queues.
+        PF will use 65 queues on each port, the firmware will reserve 4 queues
+        for each vf, when requested queues exceed 4 queues, it need to realloc queues
+        in the left queues, the reserved queues generally can't be reused.
+        """
+        pf_eal_param = '-w {} --file-prefix=test1 --socket-mem 1024,1024'.format(self.pf_pci)
+        self.pf_pmdout.start_testpmd(self.pf_pmdout.default_cores, eal_param=pf_eal_param)
+        vf1_white_index = 0
+        vf1_white_list = ''
+        vf2_queue_number = 0
+        vf3_white_index = 0
+        vf3_white_list = ''
+        if self.nic in ['fortville_eagle']:
+            left_queues = 384 - 65 - 32 * 4
+            vf1_white_index = left_queues / 16
+            vf2_queue_number = left_queues % 16
+        elif self.nic in ['fortville_25g', 'fortville_spirit', 'fortpark_TLV']:
+            left_queues = 768 - 65 - 64 * 4
+            vf1_white_index = left_queues / 16
+            vf2_queue_number = left_queues % 16
+
+        # The white list max length is 18
+        if vf1_white_index > self.max_white_per_testpmd:
+            vf3_white_index = vf1_white_index % self.max_white_per_testpmd
+            vf1_white_index = vf1_white_index - vf3_white_index
+            self.vf3_session = self.dut.new_session()
+            self.vf3_pmdout = PmdOutput(self.dut, self.vf3_session)
+
+        self.logger.info('vf2_queue_number: {}, vf3_white_index: {}'.format(vf2_queue_number, vf3_white_index))
+
+        if vf2_queue_number > 0:
+            # The driver will alloc queues as power of 2, and queue must be equal or less than 16
+            vf2_queue_number = pow(2, int(math.log(vf2_queue_number, 2)))
+
+        # we test found that if vfs do not sort, the vf2 testpmd could not start
+        vf_pcis = []
+        for vf in self.sriov_vfs_port_0:
+            vf_pcis.append(vf.pci)
+        vf_pcis.sort()
+        for pci in vf_pcis[:vf1_white_index]:
+            vf1_white_list = vf1_white_list + '-w {} '.format(pci)
+        for pci in vf_pcis[vf1_white_index:vf1_white_index+vf3_white_index]:
+            vf3_white_list = vf3_white_list + '-w {} '.format(pci)
+
+        self.logger.info('vf1 white list: {}'.format(vf1_white_list))
+        self.logger.info('vf3_white_list: {}'.format(vf3_white_list))
+        self.logger.info('vf2_queue_number: {}'.format(vf2_queue_number))
+
+        vf1_eal_param = '{} --file-prefix=vf1 --socket-mem 1024,1024'.format(vf1_white_list)
+        self.start_testpmd_multiple_times(self.vf1_pmdout, '--rxq=16 --txq=16', vf1_eal_param)
+
+        if vf3_white_index > 0:
+            vf3_eal_param = '{} --file-prefix=vf3 --socket-mem 1024,1024'.format(vf3_white_list)
+            self.start_testpmd_multiple_times(self.vf3_pmdout, '--rxq=16 --txq=16', vf3_eal_param)
+
+        if vf2_queue_number > 0:
+            vf2_eal_param = '-w {} --file-prefix=vf2 --socket-mem 1024,1024'.format(
+                vf_pcis[vf1_white_index+vf3_white_index])
+            self.vf2_pmdout.start_testpmd(self.vf2_pmdout.default_cores, param='--rxq={0} --txq={0}'.format(
+                vf2_queue_number), eal_param=vf2_eal_param)
+
+        # Check the Max possible RX queues and TX queues of the two VFs
+        vf1_out = self.vf1_pmdout.execute_cmd('show port info all')
+        self.verify('Max possible RX queues: 16' in vf1_out, 'vf1 max RX queues is not 16')
+        if vf2_queue_number > 0:
+            vf2_out = self.vf2_pmdout.execute_cmd('show port info all')
+            self.verify('Max possible RX queues: 16' in vf2_out, 'vf2 max RX queues is not 16')
+        if vf3_white_index > 0:
+            vf3_out = self.vf3_pmdout.execute_cmd('show port info all')
+            self.verify('Max possible RX queues: 16' in vf3_out, 'vf3 max RX queues is not 16')
+
+        # check the actual queue number
+        vf1_out = self.vf1_pmdout.execute_cmd('start')
+        self.verify('RX queue number: 16 Tx queue number: 16' in vf1_out, 'vf1 actual RX/TX queues is not 16')
+        if vf2_queue_number > 0:
+            vf2_out = self.vf2_pmdout.execute_cmd('start')
+            self.verify('port 0: RX queue number: {0} Tx queue number: {0}'.format(vf2_queue_number) in vf2_out,
+                        'vf2 actual RX/TX queues is not {}'.format(vf2_queue_number))
+        if vf3_white_index > 0:
+            vf3_out = self.vf3_pmdout.execute_cmd('start')
+            self.verify('RX queue number: 16 Tx queue number: 16' in vf3_out,
+                        'vf3 actual RX/TX queues is not 16')
+
+        # Set all the ports share a same rss-hash key in testpmd vf1, vf3
+        for i in range(vf1_white_index):
+            self.vf1_pmdout.execute_cmd('port config {} rss-hash-key ipv4 {}'.format(i, self.rss_key))
+
+        for i in range(vf3_white_index):
+            self.vf3_pmdout.execute_cmd('port config {} rss-hash-key ipv4 {}'.format(i, self.rss_key))
+
+        # send packets to vf1/vf2, and check all the queues could receive packets
+        # as set promisc on, packets send by tester could be received by both vf1 and vf2
+        self.vf1_pmdout.execute_cmd('set promisc all on')
+        if vf2_queue_number > 0:
+            self.vf2_pmdout.execute_cmd('set promisc all on')
+        if vf3_white_index > 0:
+            self.vf3_pmdout.execute_cmd('set promisc all on')
+
+        self.send_packet('00:11:22:33:44:55', self.src_intf, 256)
+        vf1_out = self.vf1_pmdout.execute_cmd('stop')
+        if vf2_queue_number > 0:
+            vf2_out = self.vf2_pmdout.execute_cmd('stop')
+        if vf3_white_index > 0:
+            vf3_out = self.vf3_pmdout.execute_cmd('stop')
+
+        # check all queues in vf1 can receive packets
+        for i in range(16):
+            for j in range(vf1_white_index):
+                self.verify('Forward Stats for RX Port={:>2d}/Queue={:>2d}'.format(j, i) in vf1_out,
+                            'Testpmd vf1 port {}, queue {} did not receive packet'.format(j, i))
+            for m in range(vf3_white_index):
+                self.verify('Forward Stats for RX Port={:>2d}/Queue={:>2d}'.format(m, i) in vf3_out,
+                            'Testpmd vf3 port {}, queue {} did not receive packet'.format(m, i))
+
+        # check all queues in vf2 can receive packets
+        for i in range(vf2_queue_number):
+            self.verify('Forward Stats for RX Port= 0/Queue={:>2d}'.format(i) in vf2_out,
+                        'Testpmd vf2 queue {} did not receive packet'.format(i))
+
+    def test_set_max_queue_per_vf_on_one_pf(self):
+        """
+        Test case 2: set max queue number per vf on one pf port
+        Testpmd should not crash.
+        """
+        # test queue-number-per-vf exceed hardware maximum
+        pf_eal_param = '-w {},queue-num-per-vf=16 --file-prefix=test1 --socket-mem 1024,1024'.format(self.pf_pci)
+        out = self.pf_pmdout.start_testpmd(self.pf_pmdout.default_cores, eal_param=pf_eal_param)
+        self.verify('exceeds the hardware maximum' in out, 'queue number per vf limited error')
+        out = self.pf_pmdout.execute_cmd('start')
+        self.verify('io packet forwarding' in out, 'testpmd not work normally')
+
+    def start_testpmd_multiple_times(self, pmdout, param, eal_param, retry_times=3):
+        # There is bug that start testpmd with multiple vf for the first time will fail,
+        # and it has been fixed at commit id dbda2092deb5ee5988449330c6e28e9d1fb97c19.
+        while retry_times:
+            try:
+                pmdout.start_testpmd(pmdout.default_cores, param=param, eal_param=eal_param)
+                break
+            except Exception as e:
+                self.logger.info('start testpmd occurred exception: {}'.format(e))
+            retry_times = retry_times - 1
+            time.sleep(1)
+            self.logger.info('try start testpmd the {} times'.format(retry_times))
+
+    def tear_down(self):
+        if getattr(self, 'pf_pmdout', None):
+            self.pf_pmdout.execute_cmd('quit', '# ')
+
+        if getattr(self, 'vf1_pmdout', None):
+            self.vf1_pmdout.execute_cmd('quit', '# ', timeout=200)
+
+        if getattr(self, 'vf2_pmdout', None):
+            self.vf2_pmdout.execute_cmd('quit', '# ')
+
+        if getattr(self, 'vf3_pmdout', None):
+            self.vf3_pmdout.execute_cmd('quit', '# ', timeout=150)
+
+    def tear_down_all(self):
+        self.destroy_test_env()
-- 
1.8.3.1


  parent reply	other threads:[~2019-10-12  9:52 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-12  9:57 [dts] [PATCH V1 1/3] framework/pmd_output:fix a bug in execute_cmd Haiyang Zhao
2019-10-12  9:57 ` [dts] [PATCH V1 2/3] test_plans/runtime_vf_queue_number_maxinum: update test plan Haiyang Zhao
2019-10-12  9:57 ` Haiyang Zhao [this message]
2019-10-21  2:23 ` [dts] [PATCH V1 1/3] framework/pmd_output:fix a bug in execute_cmd 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=1570874241-92780-3-git-send-email-haiyangx.zhao@intel.com \
    --to=haiyangx.zhao@intel.com \
    --cc=dts@dpdk.org \
    /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).