[dts] [PATCH 3/4] framework: reorganize DUT and Tester port initialize sequence

Marvin Liu yong.liu at intel.com
Fri Jan 23 09:26:58 CET 2015


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

DUT port initialization sequence: scan,restore,rescan,load config
Test port initialization sequence: modprobe, interface up
Separate restore interface function from DUT and Tester.

Signed-off-by: Marvinliu <yong.liu at intel.com>
---
 framework/crb.py          |  53 ++++----------
 framework/dut.py          | 181 +++++++++++++++++++++++++++++++++++-----------
 framework/project_dpdk.py |  22 ++----
 framework/tester.py       |  30 ++++++++
 4 files changed, 190 insertions(+), 96 deletions(-)

diff --git a/framework/crb.py b/framework/crb.py
index aca62c1..d7a1afd 100644
--- a/framework/crb.py
+++ b/framework/crb.py
@@ -133,44 +133,6 @@ class Crb(object):
         """
         self.send_expect("ip link set  %s %s" % (eth, status), "# ")
 
-    def restore_interfaces(self):
-        """
-        Restore Linux interfaces.
-        """
-        if dts.drivername == "vfio-pci":
-            self.send_expect("rmmod vfio_iommu_type1", "# ", 10)
-            self.send_expect("rmmod vfio_pci", "# ", 10)
-            self.send_expect("rmmod vfio", "# ", 10)
-        else:
-            self.send_expect("rmmod igb_uio", "# ", 10)
-        self.send_expect("modprobe igb", "# ", 20)
-        self.send_expect("modprobe ixgbe", "# ", 20)
-        self.send_expect("modprobe e1000e", "# ", 20)
-        self.send_expect("modprobe e1000", "# ", 20)
-        self.send_expect("modprobe virtio_net", "# ", 20)
-
-        try:
-            for (pci_bus, pci_id) in self.pci_devices_info:
-                if pci_id in ('8086:10fb', '8086:151c', '8086:1528', '8086:1512', '8086:154a'):
-                    self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/ixgbe/bind" % pci_bus, "# ")
-                elif pci_id in ('8086:10e8', '8086:150e', '8086:1521', '8086:10c9', '8086:1526', '8086:1533'):
-                    self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/igb/bind" % pci_bus, "# ")
-                elif pci_id in('8086:10d3', '8086:10b9'):
-                    self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/e1000e/bind" % pci_bus, "# ")
-                elif pci_id in ('8086:100f', '8086:100e'):
-                    self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/e1000/bind" % pci_bus, "# ")
-                elif pci_id in ('1af4:1000'):
-                    self.send_expect("echo 0000%s > /sys/bus/pci/drivers/virtio-pci/bind" % pci_bus, "# ")
-                else:
-                    continue
-
-                addr_array = pci_bus.split(':')
-                itf = self.get_interface_name(addr_array[0], addr_array[1])
-                self.send_expect("ifconfig %s up" % itf, "# ")
-
-        except Exception as e:
-            self.logger.error("   !!! Restore ITF: " + e.message)
-
     def pci_devices_information(self):
         """
         Scan CRB pci device information and save it into cache file.
@@ -194,7 +156,7 @@ class Crb(object):
         Look for the NIC's information (PCI Id and card type).
         """
         out = self.send_expect("lspci -nn | grep -i eth", "# ")
-        rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .* Intel Corporation .*?([\da-f]{4}:[\da-f]{4})"
+        rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .*?([\da-f]{4}:[\da-f]{4})"
         pattern = re.compile(rexp)
         match = pattern.findall(out)
         self.pci_devices_info = []
@@ -264,6 +226,19 @@ class Crb(object):
         match = pattern.findall(out)
         return match[0]
 
+    def get_device_numa(self, bus_id, devfun_id):
+        """
+        Get numa id of specified pci device
+        """
+        numa = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
+                                (bus_id, devfun_id), "# ")
+        try:
+            numa = int(numa)
+        except ValueError:
+            numa = -1
+            self.logger.warning("NUMA not available")
+        return numa
+
     def get_ipv6_addr(self, intf):
         """
         Get ipv6 address of specified pci device.
diff --git a/framework/dut.py b/framework/dut.py
index 4def144..959f499 100644
--- a/framework/dut.py
+++ b/framework/dut.py
@@ -33,6 +33,7 @@ import os
 import re
 import time
 import dts
+from config import UserConf
 from settings import NICS
 from ssh_connection import SSHConnection
 from crb import Crb
@@ -68,6 +69,7 @@ class Dut(Crb):
         self.cores = []
         self.architecture = None
         self.ports_info = None
+        self.conf = UserConf()
 
     def change_config_option(self, target, parameter, value):
         """
@@ -76,6 +78,14 @@ class Dut(Crb):
         self.send_expect("sed -i 's/%s=.*$/%s=%s/'  config/defconfig_%s" %
                          (parameter, parameter, value, target), "# ")
 
+    def set_nic_types(self, nics):
+        """
+        Set CRB NICS ready to validated.
+        """
+        self.nics = nics
+        if 'cfg' in nics:
+            self.conf.load_ports_config(self.get_ip_address())
+
     def set_toolchain(self, target):
         """
         This looks at the current target and instantiates an attribute to
@@ -136,8 +146,14 @@ class Dut(Crb):
 
         self.init_core_list()
         self.pci_devices_information()
-        self.restore_interfaces()
+        # scan ports before restore interface
         self.scan_ports()
+		# restore dut ports to kernel
+        self.restore_interfaces()
+		# rescan ports after interface up
+        self.rescan_ports()
+		# load port infor from config file
+        self.load_portconf()
         self.mount_procfs()
 
     def restore_interfaces(self):
@@ -251,7 +267,7 @@ class Dut(Crb):
 
         self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ', 30)
 
-    def get_ports(self, nic_type, perf=None, socket=None):
+    def get_ports(self, nic_type='any', perf=None, socket=None):
         """
         Return DUT port list with the filter of NIC type, whether run IXIA
         performance test, whether request specified socket.
@@ -293,7 +309,7 @@ class Dut(Crb):
         else:
             return ports
 
-    def get_ports_performance(self, nic_type, perf=None, socket=None,
+    def get_ports_performance(self, nic_type='any', perf=None, socket=None,
                               force_same_socket=True,
                               force_different_nic=True):
         """
@@ -331,6 +347,15 @@ class Dut(Crb):
 
         return biggest_set
 
+    def get_peer_pci(self, port_num):
+        """
+        return the peer pci address of dut port
+        """
+        if 'peer' not in self.ports_info[port_num]:
+            return None
+        else:
+            return self.ports_info[port_num]['peer']
+
     def get_mac_address(self, port_num):
         """
         return the port mac on dut
@@ -373,6 +398,55 @@ class Dut(Crb):
         else:
             return 1
 
+    def check_ports_available(self, pci_bus, pci_id):
+        """
+        Check that whether auto scanned ports ready to use
+        """
+        pci_addr = "%s:%s" % (pci_bus, pci_id)
+        codenames = []
+        for nic in self.nics:
+            if nic == 'any':
+                return True
+            elif nic == 'cfg':
+                if self.conf.check_port_available(pci_bus) is True:
+                    return True
+            elif nic not in NICS.keys():
+                self.logger.warning("NOT SUPPORTED NIC TYPE: %s" % nic)
+            else:
+                codenames.append(NICS[nic])
+
+        if pci_id in codenames:
+            return True
+
+        return False
+
+    def rescan_ports(self):
+        unknow_interface = dts.RED('Skipped: unknow_interface')
+
+        for port_info in self.ports_info:
+            pci_bus = port_info['pci']
+            addr_array = pci_bus.split(':')
+            bus_id = addr_array[0]
+            devfun_id = addr_array[1]
+            intf = self.get_interface_name(bus_id, devfun_id)
+            if "No such file" in intf:
+                self.logger.info("DUT: [0000:%s] %s" % (pci_bus, unknow_interface))
+            out = self.send_expect("ip link show %s" % intf, "# ")
+            if "DOWN" in out:
+                self.send_expect("ip link set %s up" % intf, "# ")
+                time.sleep(5)
+            macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
+            out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
+                                   % intf, "# ")
+            ipv6 = out.split('/')[0]
+            # Unconnected ports don't have IPv6
+            if ":" not in ipv6:
+                ipv6 = "Not connected"
+
+            port_info['mac'] = macaddr
+            port_info['intf'] = intf
+            port_info['ipv6'] = ipv6
+
     def scan_ports(self):
         """
         Scan ports information or just read it from cache file.
@@ -403,8 +477,7 @@ class Dut(Crb):
         unknow_interface = dts.RED('Skipped: unknow_interface')
 
         for (pci_bus, pci_id) in self.pci_devices_info:
-
-            if not dts.accepted_nic(pci_id):
+            if self.check_ports_available(pci_bus, pci_id) is False:
                 self.logger.info("DUT: [000:%s %s] %s" % (pci_bus, pci_id,
                                                           skipped))
                 continue
@@ -412,47 +485,11 @@ class Dut(Crb):
             addr_array = pci_bus.split(':')
             bus_id = addr_array[0]
             devfun_id = addr_array[1]
-            self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/igb_uio/unbind" % pci_bus, "# ")
-            if pci_id == '8086:10fb':
-                self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/ixgbe/bind" % pci_bus, "# ")
-            intf = self.get_interface_name(bus_id, devfun_id)
-
-            out = self.send_expect("ip link show %s" % intf, "# ")
-            if "DOWN" in out:
-                self.send_expect("ip link set %s up" % intf, "# ")
-                time.sleep(5)
-
-            self.logger.info("DUT: [000:%s %s] %s" % (pci_bus,
-                                                      pci_id,
-                                                      intf))
-
-            if "No such file" in intf:
-                self.logger.info("DUT: [000:%s %s] %s" % (pci_bus, pci_id,
-                                                          unknow_interface))
-                continue
-
-            macaddr = self.get_mac_addr(intf, bus_id, devfun_id)
-
-            out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
-                                   % intf, "# ")
-            ipv6 = out.split('/')[0]
-
-            # Unconnected ports don't have IPv6
-            if ":" not in ipv6:
-                ipv6 = "Not connected"
-
-            numa = self.send_expect("cat /sys/bus/pci/devices/0000\:%s\:%s/numa_node" %
-                                    (bus_id, devfun_id), "# ")
 
-            try:
-                numa = int(numa)
-            except ValueError:
-                numa = -1
-                self.logger.warning("NUMA not available")
+            numa = self.get_device_numa(bus_id, devfun_id)
 
             # store the port info to port mapping
-            self.ports_info.append({'pci': pci_bus, 'type': pci_id, 'intf':
-                                    intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': numa})
+            self.ports_info.append({'pci': pci_bus, 'type': pci_id, 'numa': numa})
 
     def scan_ports_uncached_freebsd(self):
         """
@@ -494,3 +531,61 @@ class Dut(Crb):
             # store the port info to port mapping
             self.ports_info.append({'pci': pci_str, 'type': pci_id, 'intf':
                                     intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': -1})
+
+    def restore_interfaces(self):
+        """
+        Restore Linux interfaces.
+        """
+        for port in self.ports_info:
+            pci_bus = port['pci']
+            pci_id = port['type']
+            # get device driver
+            driver = dts.get_nic_driver(pci_id)
+            if driver is not None:
+                # unbind device driver
+                addr_array = pci_bus.split(':')
+                bus_id = addr_array[0]
+                devfun_id = addr_array[1]
+
+                self.send_expect('echo 0000:%s > /sys/bus/pci/devices/0000\:%s\:%s/driver/unbind'
+                                 % (pci_bus, bus_id, devfun_id), '# ')
+                # bind to linux kernel driver
+                self.send_expect('modprobe %s' % driver, '# ')
+                self.send_expect('echo 0000:%s > /sys/bus/pci/drivers/%s/bind'
+                                 % (pci_bus, driver), '# ')
+                itf = self.get_interface_name(addr_array[0], addr_array[1])
+                self.send_expect("ifconfig %s up" % itf, "# ")
+
+    def load_portconf(self):
+        """
+        Load port configurations for ports_info. If manually configured infor
+        not same as auto scanned, still use infor in configuration file.
+        """
+        for port in self.ports_info:
+            pci_bus = port['pci']
+            if pci_bus in self.conf.ports_cfg:
+                port_cfg = self.conf.ports_cfg[pci_bus]
+                port_cfg['source'] = 'cfg'
+            else:
+                port_cfg = {}
+
+            if 'intf' in port_cfg:
+                if 'intf' in port:
+                    if port_cfg['intf'] != port['intf']:
+                        self.logger.warning("CONFIGURED INTERFACE NOT SAME AS SCANNED!!!")
+                port['intf'] = port_cfg['intf']
+
+            if 'mac' in port_cfg:
+                if 'mac' in port:
+                    if port_cfg['mac'] != port['mac']:
+                        self.logger.warning("CONFIGURED MACADDRESS NOT SAME AS SCANNED!!!")
+                port['mac'] = port_cfg['mac']
+
+            if 'numa' in port_cfg:
+                if 'numa' in port:
+                    if port_cfg['numa'] != port['numa']:
+                        self.logger.warning("CONFIGURED NUMA NOT SAME AS SCANNED!!!")
+                port['numa'] = port_cfg['numa']
+
+            if 'numa' in port_cfg:
+                port['peer'] = port_cfg['peer']
diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
index 6e25f1f..13be836 100644
--- a/framework/project_dpdk.py
+++ b/framework/project_dpdk.py
@@ -234,13 +234,10 @@ class DPDKdut(Dut):
         binding_list = '--bind=%s ' % driver
 
         current_nic = 0
-        for (pci_bus, pci_id) in self.pci_devices_info:
-            if dts.accepted_nic(pci_id):
-
-                if nics_to_bind is None or current_nic in nics_to_bind:
-                    binding_list += '%s ' % (pci_bus)
-
-                current_nic += 1
+        for port_info in self.ports_info:
+            if nics_to_bind is None or current_nic in nics_to_bind:
+                binding_list += '%s ' % (port_info['pci'])
+            current_nic += 1
 
         self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ')
 
@@ -252,13 +249,10 @@ class DPDKdut(Dut):
         binding_list = '-u '
 
         current_nic = 0
-        for (pci_bus, pci_id) in self.pci_devices_info:
-            if dts.accepted_nic(pci_id):
-
-                if nics_to_bind is None or current_nic in nics_to_bind:
-                    binding_list += '%s ' % (pci_bus)
-
-                current_nic += 1
+        for port_info in self.ports_info:
+            if nics_to_bind is None or current_nic in nics_to_bind:
+                binding_list += '%s ' % (port_info['pci'])
+            current_nic += 1
 
         self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ', 30)
 
diff --git a/framework/tester.py b/framework/tester.py
index 2c023dd..345ab41 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -170,6 +170,24 @@ class Tester(Crb):
         else:
             return 'down'
 
+    def restore_interfaces(self):
+        """
+        Restore Linux interfaces.
+        """
+        self.send_expect("modprobe igb", "# ", 20)
+        self.send_expect("modprobe ixgbe", "# ", 20)
+        self.send_expect("modprobe e1000e", "# ", 20)
+        self.send_expect("modprobe e1000", "# ", 20)
+
+        try:
+            for (pci_bus, pci_id) in self.pci_devices_info:
+                addr_array = pci_bus.split(':')
+                itf = self.get_interface_name(addr_array[0], addr_array[1])
+                self.send_expect("ifconfig %s up" % itf, "# ")
+
+        except Exception as e:
+            self.logger.error("   !!! Restore ITF: " + e.message)
+
     def scan_ports(self):
         """
         Scan all ports on tester and save port's pci/mac/interface.
@@ -253,6 +271,18 @@ class Tester(Crb):
         hits = [False] * len(self.ports_info)
 
         for dutPort in range(nrPorts):
+            peer = self.dut.get_peer_pci(dutPort)
+            if peer is not None:
+                for localPort in range(len(self.ports_info)):
+                    if self.ports_info[localPort]['pci'] == peer:
+                        hits[localPort] = True
+                        self.ports_map[dutPort] = localPort
+                        break
+                if self.ports_map[dutPort] == -1:
+                    self.logger.error("CONFIGURED TESTER PORT CANNOT FOUND!!!")
+                else:
+                    continue  # skip ping6 map
+
             for localPort in range(len(self.ports_info)):
                 if hits[localPort]:
                     continue
-- 
1.9.3



More information about the dts mailing list