Signed-off-by: xu,gang --- tests/TestSuite_interrupt_pmd.py | 277 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 tests/TestSuite_interrupt_pmd.py diff --git a/tests/TestSuite_interrupt_pmd.py b/tests/TestSuite_interrupt_pmd.py new file mode 100644 index 0000000..0f195da --- /dev/null +++ b/tests/TestSuite_interrupt_pmd.py @@ -0,0 +1,277 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2017 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. + +Rx interrupt pmd test suite. +""" + +import string +import re +import time +import utils +from test_case import TestCase +from utils import create_mask +from packet import Packet, sniff_packets, load_sniff_packets + + +class TestIntrPmd(TestCase): + + VIFO_MODES = ['legacy', 'msi', 'msix'] + IGBUIO_MODES = ['legacy', 'msix'] + + def set_up_all(self): + """ + Run before each test suite. + """ + self.dut_ports = self.dut.get_ports(self.nic) + self.verify(len(self.dut_ports) >= 2, "Insufficient ports") + self.cores = self.dut.get_core_list("1S/4C/1T") + self.portmask = utils.create_mask(self.dut_ports) + self.coremask = create_mask(self.cores) + + self.path = "./examples/l3fwd-power/build/l3fwd-power" + self.build_app() + + def build_app(self): + """ + build sample app + """ + out = self.dut.send_expect("make -C examples/l3fwd-power", "# ") + self.verify("Error" not in out, "compilation error 1") + self.verify("No such file" not in out, "compilation error 2") + + def set_up(self): + """ + Run before each test case. + """ + pass + + def scapy_send_packet(self, queuenum=1): + """ + Send a packet to port + """ + self.dmac = self.dut.get_mac_address(self.dut_ports[0]) + txport = self.tester.get_local_port(self.dut_ports[0]) + self.txItf = self.tester.get_interface(txport) + if queuenum == 1: + self.tester.scapy_append( + 'sendp([Ether(dst="%s")/IP()/UDP()/Raw(\'X\'*18)], iface="%s")' % (self.dmac, self.txItf)) + elif queuenum == 2: + for i in range(16): + self.tester.scapy_append( + 'sendp([Ether(dst="%s")/IP(dst="127.0.0.%d")/UDP()/Raw(\'X\'*18)], iface="%s")' % (self.dmac, i, self.txItf)) + else: + for i in range(256): + self.tester.scapy_append( + 'sendp([Ether(dst="%s")/IP(dst="127.0.0.%d")/UDP()/Raw(\'X\'*18)], iface="%s")' % (self.dmac, i, self.txItf)) + self.tester.scapy_execute() + + def test_diff_queue(self): + """ + Verify interrupt pmd work fine with different queues + """ + coremask = create_mask(self.cores) + # A number is a “digit([0-9]+)”; + if self.nic == "niantic": + self.max_queue = 10 + elif "kawela" in self.nic: + self.max_queue = 10 + elif self.nic == "powerville" or self.nic == "bartonhills": + self.max_queue = 8 + elif self.nic == "springville": + self.max_queue = 4 + elif self.nic == "fortville_eagle": + self.max_queue = 10 + else: + self.max_queue = 2 + + for queue in range(1, self.max_queue): + #--config (port,queue,lcore) + config_cmd = "--config=\"" + for idx in range(queue): + config_cmd += "(0,%d,%s)," % (idx, self.cores[0]) + config_cmd += "\"" + cmd = self.path + \ + " -c %s -n %d -- -p %s -P " % (coremask, + self.dut.get_memory_channels(), self.portmask) + cmd += config_cmd + put = self.dut.send_expect( + cmd, "L3FWD_POWER", 60) + self.scapy_send_packet(self.max_queue) + out = self.dut.get_session_output(timeout=60) + self.dut.send_expect("^C", "# ") + if self.drivername == "igb_uio": + self.verify( + "lcore %s is waked up from rx interrupt on port 0" % + self.cores[0] in out, "lcore %s not waked up" % self.cores[0]) + self.verify("lcore %s sleeps until interrupt triggers" % + self.cores[0] in out, "lcore %s not sleeps" % self.cores[0]) + elif self.drivername == "vfio-pci": + lcore_wake = re.findall( + "lcore (\d) is waked up from rx interrupt", out) + self.verify( + self.cores[0] in lcore_wake, "lcore %s not waked up" % self.cores[0]) + lcore_sleep = re.findall( + "lcore (\d) sleeps until interrupt triggers", out) + self.verify( + self.cores[0] in lcore_sleep, "lcore %s not sleeps" % self.cores[0]) + use_queues = re.findall( + "is waked up from rx interrupt on port 0 queue (\d)", out) + for idx in range(queue): + self.verify( + str(idx) in use_queues, "the interrupt not ues diff queues") + + def change_port_conf(self, lsc_enable=True, rxq_enable=True): + """ + change interrupt enable + """ + sed_cmd_fmt = "/intr_conf.*=.*{/,/\}\,$/c\ .intr_conf = {\\n\\t\\t.lsc = %d,\\n\\t\\t.rxq = %d,\\n\\t}," + lsc = 0 + rxq = 0 + if lsc_enable: + lsc = 1 + if rxq_enable: + rxq = 1 + sed_cmd_str = sed_cmd_fmt % (lsc, rxq) + out = self.dut.send_expect( + "sed -i '%s' examples/l3fwd-power/main.c" % sed_cmd_str, "# ", 60) + + def test_pf_lsc(self): + """ + Verify diff interrupt enable + """ + if self.drivername == "igb_uio": + for mode in self.IGBUIO_MODES: + param = "intr_mode=%s" % mode + + self.dut.send_expect("rmmod igb_uio", "# ") + self.dut.send_expect( + "insmod ./%s/kmod/igb_uio.ko %s" % (self.target, param), "# ") + self.dut.bind_interfaces_linux() + + cmd = self.path + " -c %s -n %d -- -p %s -P " \ + "--config=\"(0,0,%s),(1,0,%s)\"" \ + % (self.coremask, self.dut.get_memory_channels(), + self.portmask, self.cores[0], self.cores[1]) + + # build l3fwd-power with only lsc interrupt enable + self.change_port_conf(lsc_enable=True, rxq_enable=False) + self.build_app() + self.verify_lsc_status(cmd, lsc=True) + + # build l3fwd-power with lsc & rxq interrupt enable + self.change_port_conf(lsc_enable=True, rxq_enable=True) + self.build_app() + self.verify_lsc_status(cmd, lsc=False) + elif self.drivername == "vfio-pci": + # build l3fwd-power with lsc and rx interrupt enable + self.change_port_conf(lsc_enable=True, rxq_enable=True) + self.build_app() + # verify all vfio supported interrupt modes + for mode in self.VIFO_MODES: + cmd = self.path + " -c %s -n %d --vfio-intr=%s -- -p %s -P " \ + "--config=\"(0,0,%s),(1,0,%s)\"" \ + % (self.coremask, self.dut.get_memory_channels(), mode, + self.portmask, self.cores[0], self.cores[1]) + + if mode != "msix": + self.verify_lsc_status(cmd, lsc=False) + else: + self.verify_lsc_status(cmd, lsc=True) + + # build l3fwd-power with only lsc interrupt enable + self.change_port_conf(lsc_enable=True, rxq_enable=False) + self.build_app() + + # verify all vfio supported interrupt modes + for mode in self.VIFO_MODES: + cmd = self.path + " -c %s -n %d --vfio-intr=%s -- -p %s -P " \ + "--config=\"(0,0,%s),(1,0,%s)\"" \ + % (self.coremask, self.dut.get_memory_channels(), mode, + self.portmask, self.cores[0], self.cores[1]) + + self.verify_lsc_status(cmd, lsc=True) + elif self.drivername == "uio_pci_generic": + cmd = self.path + " -c %s -n %d -- -p %s -P " \ + "--config=\"(0,0,%s),(1,0,%s)\"" \ + % (self.coremask, self.dut.get_memory_channels(), + self.portmask, self.cores[0], self.cores[1]) + + # start l3fwd-power + # build l3fwd-power with only lsc interrupt enable + self.change_port_conf(lsc_enable=True, rxq_enable=False) + self.build_app() + self.verify_lsc_status(cmd, lsc=True) + + # build l3fwd-power with lsc & rxq interrupt enable + self.change_port_conf(lsc_enable=True, rxq_enable=True) + self.build_app() + self.verify_lsc_status(cmd, lsc=False) + + def verify_lsc_status(self, cmd, lsc=True): + # start l3fwd-power + out = self.dut.send_expect(cmd, "L3FWD_POWER", 60) + # wait for linke ready + time.sleep(10) + + if lsc: + for idx in range(2): + txport = self.tester.get_local_port(self.dut_ports[idx]) + txItf = self.tester.get_interface(txport) + + self.tester.send_expect("ifconfig %s down" % txItf, "# ") + out = self.dut.get_session_output(timeout=10) + self.verify("Port %d: Link Down" % + idx in out, "LSC can't detected link down") + self.tester.send_expect("ifconfig %s up" % txItf, "# ") + out = self.dut.get_session_output(timeout=10) + self.verify("Port %d: Link Up" % + idx in out, "LSC can't detected link up") + else: + self.verify("lsc won't enable" in out, "LSC should not enabled") + + self.dut.kill_all() + time.sleep(2) + + def tear_down(self): + """ + Run after each test suite. + """ + self.dut.kill_all() + time.sleep(2) + + def tear_down_all(self): + """ + Run after each test suite. + """ + pass -- 1.9.3