[dts] [PATCH] Add vxlan sample performance test case

Yong Liu yong.liu at intel.com
Wed Jun 10 04:26:50 CEST 2015


From: Marvin Liu <yong.liu at intel.com>

This case will measure decap/encap/chkcsum performance of vxlan sample.
Signed-off-by: Marvin Liu <yong.liu at intel.com>

diff --git a/test_plans/vxlan_sample_test_plan.rst b/test_plans/vxlan_sample_test_plan.rst
index 93136fd..f440148 100644
--- a/test_plans/vxlan_sample_test_plan.rst
+++ b/test_plans/vxlan_sample_test_plan.rst
@@ -223,3 +223,33 @@ Verify that packet recevied by virtIO port0 and forwarded by virtIO port1::
 
 Verify that four separated vxlan packets received on PF devices.
 Make sure tcp packet payload is 256, 256, 256 and 124.
+
+Test Case: Vxlan Sample Performance Benchmarking
+================================================
+The throughput is measured for different operations taken by vxlan sample.
+Virtio single mean there's only one flow and forwarded by single port in vm.
+Virtio two mean there're two flows and forwarded by both two ports in vm.
+
++================+===========+=======+============+
+| Function       | VirtIO    | Mpps  | % linerate |
++================+===========+=======+============+
+| Decap          | Single    |       |            |
++----------------+-----------+-------+------------+
+| Encap          | Single    |       |            |
++----------------+-----------+-------+------------+
+| Decap&Encap    | Single    |       |            |
++----------------+-----------+-------+------------+
+| Checksum       | Single    |       |            |
++----------------+-----------+-------+------------+
+| Checksum&Decap | Single    |       |            |
++----------------+-----------+-------+------------+
+| Decap          | Two Ports |       |            |
++----------------+-----------+-------+------------+
+| Encap          | Two Ports |       |            |
++----------------+-----------+-------+------------+
+| Decap&Encap    | Two Ports |       |            |
++----------------+-----------+-------+------------+
+| Checksum       | Two Ports |       |            |
++----------------+-----------+-------+------------+
+| Checksum&Decap | Two Ports |       |            |
++----------------+-----------+-------+------------+
diff --git a/tests/TestSuite_vxlan_sample.py b/tests/TestSuite_vxlan_sample.py
index eccace7..ef94c87 100644
--- a/tests/TestSuite_vxlan_sample.py
+++ b/tests/TestSuite_vxlan_sample.py
@@ -60,6 +60,9 @@ from scapy.config import conf
 from scapy.route import *
 
 
+PACKET_LEN = 128
+
+
 class TestVxlanSample(TestCase):
     FEAT_ENABLE = 1
     FEAT_DISABLE = 0
@@ -72,8 +75,9 @@ class TestVxlanSample(TestCase):
         Run before each test suite.
         """
         # Change the config file to support vhost and recompile the package.
-        self.dut.send_expect(
-            "sed -i -e 's/RTE_LIBRTE_VHOST=n$/RTE_LIBRTE_VHOST=y/' config/common_linuxapp", "# ", 30)
+        self.dut.send_expect("sed -i -e 's/RTE_LIBRTE_VHOST=n$/"
+                             + "RTE_LIBRTE_VHOST=y/' config/"
+                             + "common_linuxapp", "# ", 30)
         # temporary disable skip_setup
         skip_setup = self.dut.skip_setup
         self.dut.skip_setup = False
@@ -81,10 +85,11 @@ class TestVxlanSample(TestCase):
         self.dut.skip_setup = skip_setup
 
         # this feature only enable in FVL now
-        self.verify(
-            self.nic in ["fortville_eagle", "fortville_spirit", "fortville_spirit_single"], "Vxlan Only supported by Fortville")
+        self.verify(self.nic in ["fortville_eagle", "fortville_spirit",
+                                 "fortville_spirit_single"],
+                    "Vxlan Only supported by Fortville")
         # Based on h/w type, choose how many ports to use
-        self.dut_ports = self.dut.get_ports(self.nic)
+        self.dut_ports = self.dut.get_ports()
 
         # Verify that enough ports are available
         self.verify(len(self.dut_ports) >= 1, "Insufficient ports for testing")
@@ -106,19 +111,43 @@ class TestVxlanSample(TestCase):
         self.dut.send_expect("insmod ./eventfd_link.ko", "# ")
         self.dut.send_expect("cd ../../..", "# ")
         out = self.dut.send_expect("lsmod |grep eventfd_link", "# ")
-        self.verify("eventfd_link" in out, "Failed to insmod eventfd_link driver")
+        self.verify("eventfd_link" in out,
+                    "Failed to insmod eventfd_link driver")
 
         self.def_mac = "00:00:20:00:00:20"
         self.vm_dut = None
         self.tep_app = "./examples/tep_termination/build/tep_termination"
         self.vxlan_port = 4789
-        self.vm_testpmd = "./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 3 -- -i --txqflags=0xf00 --disable-hw-vlan"
+        self.vm_testpmd = "./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 3" \
+                          + " -- -i --txqflags=0xf00 --disable-hw-vlan"
 
         # params for tep_termination
         self.cores = self.dut.get_core_list("1S/4C/1T", socket=self.socket)
         self.capture_file = "/tmp/vxlan_cap.pcap"
         self.def_mss = 256
 
+        # performance measurement, checksum based on encap
+        self.perf_cfg = [{'Func': 'Decap', 'VirtIO': 'Single', 'Mpps': {},
+                         'pct': {}},
+                         {'Func': 'Encap', 'VirtIO': 'Single', 'Mpps': {},
+                          'pct': {}},
+                         {'Func': 'Decap&Encap', 'VirtIO': 'Single',
+                          'Mpps': {}, 'pct': {}},
+                         {'Func': 'Checksum', 'VirtIO': 'Single',
+                          'Mpps': {}, 'pct': {}},
+                         {'Func': 'Checksum&Decap', 'VirtIO': 'Single',
+                          'Mpps': {}, 'pct': {}},
+                         {'Func': 'Decap', 'VirtIO': 'Two Ports', 'Mpps': {},
+                          'pct': {}},
+                         {'Func': 'Encap', 'VirtIO': 'Two Ports', 'Mpps': {},
+                          'pct': {}},
+                         {'Func': 'Decap&Encap', 'VirtIO': 'Two Ports',
+                          'Mpps': {}, 'pct': {}},
+                         {'Func': 'Checksum', 'VirtIO': 'Two Ports',
+                          'Mpps': {}, 'pct': {}},
+                         {'Func': 'Checksum&Decap', 'VirtIO': 'Two Ports',
+                          'Mpps': {}, 'pct': {}}]
+
     def set_up(self):
         """
         Run before each test case.
@@ -145,19 +174,24 @@ class TestVxlanSample(TestCase):
         elif self.running_case == "test_vxlan_sample_tso":
             chksum = self.FEAT_ENABLE
 
-        tep_cmd_temp = self.tep_app + " -c %(COREMASK)s -n %(CHANNELS)d --socket-mem 2048,2048 -- -p 0x1 " \
-            + "--udp-port %(VXLAN_PORT)d --nb-devices %(NB_DEVS)d --filter-type %(FILTERS)d " \
+        tep_cmd_temp = self.tep_app + " -c %(COREMASK)s -n %(CHANNELS)d " \
+            + "--socket-mem 2048,2048 -- -p 0x1 " \
+            + "--udp-port %(VXLAN_PORT)d --nb-devices %(NB_DEVS)d " \
+            + "--filter-type %(FILTERS)d " \
             + "--tx-checksum %(TX_CHKS)d --encap %(ENCAP)d --decap %(DECAP)d"
 
-        tep_cmd = tep_cmd_temp % {'COREMASK': self.coremask, 'CHANNELS': self.dut.get_memory_channels(),
-                                  'VXLAN_PORT': self.vxlan_port, 'NB_DEVS': vm_num * 2,
-                                  'FILTERS': self.OUTER_INNER_VNI, 'TX_CHKS': chksum,
-                                  'ENCAP': encap, 'DECAP': decap}
+        tep_cmd = tep_cmd_temp % {
+            'COREMASK': self.coremask,
+            'CHANNELS': self.dut.get_memory_channels(),
+            'VXLAN_PORT': self.vxlan_port, 'NB_DEVS': vm_num * 2,
+            'FILTERS': self.OUTER_INNER_VNI, 'TX_CHKS': chksum,
+            'ENCAP': encap, 'DECAP': decap}
 
         if self.running_case == "test_vxlan_sample_tso":
             tep_cmd += " --tso-segsz=%d" % self.def_mss
 
-        self.prepare_vxlan_sample_env(tep_cmd, vm_num=vm_num)
+        if self.running_case != "test_perf_vxlan_sample":
+            self.prepare_vxlan_sample_env(tep_cmd, vm_num=vm_num)
 
         pass
 
@@ -213,12 +247,10 @@ class TestVxlanSample(TestCase):
         Start testpmd in virtual machine
         """
         if vm_id == 0 and self.vm_dut is not None:
-            # create coremask
-            self.vm_pmd = PmdOutput(self.vm_dut)
             # start testpmd
             self.vm_dut.send_expect(self.vm_testpmd, "testpmd>", 20)
             # set fwd mac
-            self.vm_dut.send_expect("set fwd mac", "testpmd>")
+            self.vm_dut.send_expect("set fwd io", "testpmd>")
             # start tx_first
             self.vm_dut.send_expect("start tx_first", "testpmd>")
 
@@ -247,12 +279,17 @@ class TestVxlanSample(TestCase):
         self.vm_testpmd_start(vm_id=0)
         self.send_and_verify(vm_id=0, vf_id=0, pkt_type="vxlan_tcp_tso")
 
-    def start_capture(self, itf, pkt_smac="", count=1):
+    def start_capture(self, itf, pkt_smac="", pkt_dmac="", count=1):
         self.tester.send_expect("rm -f %s" % self.capture_file, "# ")
         self.tester.scapy_background()
-        self.tester.scapy_append(
-            'p = sniff(filter="ether src %s",' % pkt_smac +
-            'iface="%s", count=%d, timeout=5)' % (itf, count))
+        if pkt_smac != "":
+            self.tester.scapy_append(
+                'p = sniff(filter="ether src %s",' % pkt_smac +
+                'iface="%s", count=%d, timeout=5)' % (itf, count))
+        if pkt_dmac != "":
+            self.tester.scapy_append(
+                'p = sniff(filter="ether dst %s",' % pkt_smac +
+                'iface="%s", count=%d, timeout=5)' % (itf, count))
         self.tester.scapy_append(
             'wrpcap(\"%s\", p)' % self.capture_file)
         self.tester.scapy_foreground()
@@ -277,13 +314,16 @@ class TestVxlanSample(TestCase):
 
         if pkt_type == "normal_udp":
             self.start_capture(tester_iface, pkt_smac=self.pf_mac)
-            self.tester.scapy_append('sendp([Ether(dst="%s")/IP()/UDP()/Raw("X"*18)], iface="%s")' % (self.pf_mac, tester_iface))
+            self.tester.scapy_append(
+                'sendp([Ether(dst="%s")/IP()/UDP()/Raw("X"*18)], iface="%s")'
+                % (self.pf_mac, tester_iface))
             self.tester.scapy_execute()
             time.sleep(5)
 
             pkts = self.transfer_capture_file()
             self.verify(len(pkts) >= 1, "Failed to capture packets")
-            self.verify(pkts[0].haslayer(Vxlan) == 1, "Packet not encapsulated")
+            self.verify(pkts[0].haslayer(Vxlan) == 1,
+                        "Packet not encapsulated")
             try:
                 payload = str(pkts[0][UDP][Vxlan][UDP].payload)
                 for i in range(18):
@@ -293,7 +333,8 @@ class TestVxlanSample(TestCase):
                 print dts.RED("Failure in checking packet payload")
 
             if case_pass:
-                print dts.GREEN("Check normal udp packet forward pass on virtIO port %d" % vf_id)
+                print dts.GREEN("Check normal udp packet forward pass on "
+                                "virtIO port %d" % vf_id)
 
         if pkt_type == "vxlan_udp_decap":
             # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
@@ -301,17 +342,13 @@ class TestVxlanSample(TestCase):
             params['vni'] = 1000 + vm_id
             mac_incr = 2 * vm_id + vf_id
             params['inner_mac_dst'] = self.mac_address_add(mac_incr)
-            if vf_id == 0:
-                smac = self.mac_address_add(2 * vm_id + 1)
-            else:
-                smac = self.mac_address_add(2 * vm_id)
 
             # create vxlan pcap file and tranfer it to tester
             vxlan_pkt = VxlanTestConfig(self, **params)
             vxlan_pkt.create_pcap(scp=True)
 
             # start capture
-            self.start_capture(tester_iface, pkt_smac=smac)
+            self.start_capture(tester_iface, pkt_dmac=params['inner_mac_dst'])
             vxlan_pkt.send_pcap(tester_iface)
             time.sleep(5)
 
@@ -319,7 +356,8 @@ class TestVxlanSample(TestCase):
             pkts = self.transfer_capture_file()
             # check packet number and payload
             self.verify(len(pkts) >= 1, "Failed to capture packets")
-            self.verify(pkts[0].haslayer(Vxlan) == 0, "Packet not de-encapsulated")
+            self.verify(pkts[0].haslayer(Vxlan) == 0,
+                        "Packet not de-encapsulated")
 
             try:
                 payload = str(pkts[0][UDP].payload)
@@ -330,7 +368,8 @@ class TestVxlanSample(TestCase):
                 print dts.RED("Failure in checking packet payload")
 
             if case_pass:
-                print dts.GREEN("Check vxlan packet decap pass on virtIO port %d" % vf_id)
+                print dts.GREEN("Check vxlan packet decap pass on virtIO port"
+                                " %d" % vf_id)
 
         if pkt_type == "vxlan_udp":
             # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
@@ -352,7 +391,8 @@ class TestVxlanSample(TestCase):
             pkts = self.transfer_capture_file()
             # check packet number and payload
             self.verify(len(pkts) >= 1, "Failed to capture packets")
-            self.verify(pkts[0].haslayer(Vxlan) == 1, "Packet not encapsulated")
+            self.verify(pkts[0].haslayer(Vxlan) == 1,
+                        "Packet not encapsulated")
             try:
                 payload = str(pkts[0][UDP][Vxlan][UDP].payload)
                 for i in range(18):
@@ -362,7 +402,8 @@ class TestVxlanSample(TestCase):
                 print dts.RED("Failure in checking packet payload")
 
             if case_pass:
-                print dts.GREEN("Check vxlan packet decap and encap pass on virtIO port %d" % vf_id)
+                print dts.GREEN("Check vxlan packet decap and encap pass on "
+                                "virtIO port %d" % vf_id)
 
         if pkt_type == "vxlan_udp_chksum":
             params['inner_l4_type'] = 'UDP'
@@ -398,17 +439,20 @@ class TestVxlanSample(TestCase):
             pkts = self.transfer_capture_file()
             # check packet number and payload
             self.verify(len(pkts) >= 1, "Failed to capture packets")
-            self.verify(pkts[0].haslayer(Vxlan) == 1, "Packet not encapsulated")
+            self.verify(pkts[0].haslayer(Vxlan) == 1,
+                        "Packet not encapsulated")
             chksums = vxlan_pkt.get_chksums(pcap='vxlan_cap.pcap')
             for key in chksums_ref:
                 if 'inner' in key:  # only check inner packet chksum
                     self.verify(chksums[key] == chksums_ref[key],
-                                "%s not matched to %s" % (key, chksums_ref[key]))
+                                "%s not matched to %s"
+                                % (key, chksums_ref[key]))
 
             print dts.GREEN("%s checksum pass" % params['inner_l4_type'])
 
         if pkt_type == "vxlan_tcp_tso":
-            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac + tcp
+            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac +
+            # tcp
             params['inner_l4_type'] = 'TCP'
             params['outer_mac_dst'] = self.pf_mac
             params['vni'] = 1000 + vm_id
@@ -430,10 +474,12 @@ class TestVxlanSample(TestCase):
             self.verify(len(pkts) == 4, "Failed to capture tso packets")
             length = 0
             for pkt in pkts:
-                self.verify(pkt.haslayer(Vxlan) == 1, "Packet not encapsulated")
+                self.verify(pkt.haslayer(Vxlan) == 1,
+                            "Packet not encapsulated")
                 try:
                     payload = str(pkt[UDP][Vxlan][TCP].payload)
-                    self.verify(len(payload) <= self.def_mss, "TCP payload oversized")
+                    self.verify(len(payload) <= self.def_mss,
+                                "TCP payload oversized")
                     length += len(payload)
                 except:
                     case_pass = False
@@ -441,7 +487,124 @@ class TestVxlanSample(TestCase):
 
             self.verify(length == 892, "Total tcp payload size not match")
             if case_pass:
-                print dts.GREEN("Vxlan packet tso pass on virtIO port %d" % vf_id)
+                print dts.GREEN("Vxlan packet tso pass on virtIO port %d"
+                                % vf_id)
+
+    def test_perf_vxlan_sample(self):
+        # vxlan payload length for performance test
+        # inner packet not contain crc, should need add four
+        vxlan_payload = PACKET_LEN - HEADER_SIZE['eth'] - \
+            HEADER_SIZE['ip'] - HEADER_SIZE['udp'] - \
+            HEADER_SIZE['vxlan'] - HEADER_SIZE['eth'] - \
+            HEADER_SIZE['ip'] - HEADER_SIZE['udp'] + 4
+
+        vxlansample_header = ['Type', 'Queue', 'Mpps', '% linerate']
+        dts.results_table_add_header(vxlansample_header)
+        for perf_cfg in self.perf_cfg:
+            func = perf_cfg['Func']
+            if func is 'Decap':
+                encap = self.FEAT_DISABLE
+                decap = self.FEAT_ENABLE
+                chksum = self.FEAT_DISABLE
+            elif func is 'Encap':
+                encap = self.FEAT_ENABLE
+                decap = self.FEAT_DISABLE
+                chksum = self.FEAT_DISABLE
+            elif func is 'Decap&Encap':
+                encap = self.FEAT_ENABLE
+                decap = self.FEAT_ENABLE
+                chksum = self.FEAT_DISABLE
+            elif func is 'Checksum':
+                encap = self.FEAT_ENABLE
+                decap = self.FEAT_DISABLE
+                chksum = self.FEAT_ENABLE
+            elif func is 'Checksum&Decap':
+                encap = self.FEAT_ENABLE
+                decap = self.FEAT_ENABLE
+                chksum = self.FEAT_ENABLE
+
+            tep_cmd_temp = self.tep_app + " -c %(COREMASK)s -n %(CHANNELS)d " \
+                + "--socket-mem 2048,2048 -- -p 0x1 --udp-port " \
+                + "%(VXLAN_PORT)d  --nb-devices %(NB_DEVS)d --filter-type " \
+                + "%(FILTERS)d --tx-checksum %(TX_CHKS)d --encap %(ENCAP)d " \
+                + "--decap %(DECAP)d --rx-retry 1 --rx-retry-num 4 " \
+                + "--rx-retry-delay 15"
+
+            tep_cmd = tep_cmd_temp % {
+                'COREMASK': self.coremask,
+                'CHANNELS': self.dut.get_memory_channels(),
+                'VXLAN_PORT': self.vxlan_port, 'NB_DEVS': 2,
+                'FILTERS': self.OUTER_INNER_VNI, 'TX_CHKS': chksum,
+                'ENCAP': encap, 'DECAP': decap}
+
+            self.prepare_vxlan_sample_env(tep_cmd, vm_num=1)
+            self.vm_testpmd_start(vm_id=0)
+
+            # create vxlan packet pf mac + vni=1000 + inner virtIO port0 mac
+            params = {}
+            params['outer_mac_dst'] = self.pf_mac
+            params['vni'] = 1000
+            mac_incr = 0
+            params['inner_mac_dst'] = self.mac_address_add(mac_incr)
+            params['payload_size'] = vxlan_payload
+            params['pcap_file'] = 'vxlan_sample.pcap'
+
+            # create vxlan pcap file and tranfer it to tester
+            vxlan_pkt = VxlanTestConfig(self, **params)
+            vxlan_pkt.create_pcap(scp=False)
+
+            if perf_cfg['VirtIO'] == "Two Ports":
+                # create vxlan packet pf mac + vni=1000 + inner virtIO port0
+                # mac
+                params['outer_mac_dst'] = self.pf_mac
+                params['vni'] = 1000
+                mac_incr = 1
+                params['inner_mac_dst'] = self.mac_address_add(mac_incr)
+                params['pcap_file'] = 'vxlan_sample_1.pcap'
+
+                # create vxlan pcap file and tranfer it to tester
+                vxlan_pkt = VxlanTestConfig(self, **params)
+                vxlan_pkt.create_pcap(scp=False)
+
+                self.combine_pcap("vxlan_sample.pcap", "vxlan_sample_1.pcap")
+
+            self.tester.session.copy_file_to("vxlan_sample.pcap")
+
+            # config the flows
+            tgen_input = []
+            tgen_input.append((self.tester.get_local_port(self.pf),
+                               self.tester.get_local_port(self.pf),
+                               "vxlan_sample.pcap"))
+
+            # run traffic generator
+            _, pps = self.tester.traffic_generator_throughput(tgen_input)
+
+            self.vm_dut.send_expect("stop", "testpmd>")
+            self.vm_dut.send_expect("quit", "# ")
+
+            pps /= 1000000.0
+            perf_cfg['Mpps'] = pps
+            wirespeed = self.wirespeed(self.nic, PACKET_LEN, 1)
+            perf_cfg['pct'] = pps * 100 / wirespeed
+
+            table_row = [perf_cfg['Func'], perf_cfg['VirtIO'],
+                         perf_cfg['Mpps'], perf_cfg['pct']]
+
+            dts.results_table_add_row(table_row)
+
+            self.tear_down()
+
+        dts.results_table_print()
+
+    def combine_pcap(self, dest_pcap, src_pcap):
+        pkts = rdpcap(dest_pcap)
+        if len(pkts) != 1:
+            return
+
+        pkts_src = rdpcap(src_pcap)
+        pkts += pkts_src
+
+        wrpcap(dest_pcap, pkts)
 
     def tear_down(self):
         """
@@ -459,8 +622,9 @@ class TestVxlanSample(TestCase):
         Run after each test suite.
         """
         # Restore the config file and recompile the package.
-        self.dut.send_expect(
-            "sed -i -e 's/RTE_LIBRTE_VHOST=y$/RTE_LIBRTE_VHOST=n/' config/common_linuxapp", "# ", 30)
+        self.dut.send_expect("sed -i -e 's/RTE_LIBRTE_VHOST=y$/"
+                             + "RTE_LIBRTE_VHOST=n/' config/common_linuxapp",
+                             "# ", 30)
         # temporary disable skip_setup
         skip_setup = self.dut.skip_setup
         self.dut.skip_setup = False
-- 
1.9.3



More information about the dts mailing list