From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id C6CBEADA5 for ; Wed, 4 Feb 2015 07:44:08 +0100 (CET) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 03 Feb 2015 22:44:07 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,517,1418112000"; d="scan'208";a="680600844" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga002.jf.intel.com with ESMTP; 03 Feb 2015 22:44:06 -0800 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id t146i3TN005744; Wed, 4 Feb 2015 14:44:03 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t146i1AG019913; Wed, 4 Feb 2015 14:44:03 +0800 Received: (from yliu84x@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t146i1Xx019909; Wed, 4 Feb 2015 14:44:01 +0800 From: Yong Liu To: dts@dpdk.org Date: Wed, 4 Feb 2015 14:43:33 +0800 Message-Id: <1423032214-19856-4-git-send-email-yong.liu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1423032214-19856-1-git-send-email-yong.liu@intel.com> References: <1423032214-19856-1-git-send-email-yong.liu@intel.com> Subject: [dts] [PATCH v2 3/4] framework: reorganize DUT and Tester port initialize sequence X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Feb 2015 06:44:09 -0000 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 --- framework/crb.py | 66 ++++------------- framework/dut.py | 172 ++++++++++++++++++++++++++++++-------------- framework/project_dpdk.py | 22 +++--- framework/ssh_connection.py | 2 +- framework/tester.py | 32 ++++++++- 5 files changed, 175 insertions(+), 119 deletions(-) diff --git a/framework/crb.py b/framework/crb.py index d41f51b..fa03757 100644 --- a/framework/crb.py +++ b/framework/crb.py @@ -133,56 +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: - out = self.send_expect("lsmod | grep igb_uio", "#") - if "igb_uio" in out: - self.send_expect("rmmod -f 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: - """ - Check if driver is already bound before binding it. - """ - if pci_id in ('8086:10fb', '8086:151c', '8086:1528', '8086:1512', '8086:154a'): - if not os.path.exists("/sys/bus/pci/drivers/ixgbe/"+"0000:"+pci_bus): - self.send_expect("echo -n 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'): - if not os.path.exists("/sys/bus/pci/drivers/igb/"+"0000:"+pci_bus): - self.send_expect("echo -n 0000:%s > /sys/bus/pci/drivers/igb/bind" % pci_bus, "# ") - elif pci_id in('8086:10d3', '8086:10b9'): - if not os.path.exists("/sys/bus/pci/drivers/e1000e/"+"0000:"+pci_bus): - self.send_expect("echo -n 0000:%s > /sys/bus/pci/drivers/e1000e/bind" % pci_bus, "# ") - elif pci_id in ('8086:153a', '8086:153b', '8086:155a', '8086:1559'): - if not os.path.exists("/sys/bus/pci/drivers/e1000e/"+"0000:"+pci_bus): - self.send_expect("echo -n 0000:%s > /sys/bus/pci/drivers/e1000e/bind" % pci_bus, "# ") - elif pci_id in ('8086:100f', '8086:100e'): - if not os.path.exists("/sys/bus/pci/drivers/e1000/"+"0000:"+pci_bus): - self.send_expect("echo -n 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. @@ -206,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 = [] @@ -276,6 +226,20 @@ 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 9879335..cddc248 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 @@ -70,6 +71,7 @@ class Dut(Crb): self.cores = [] self.architecture = None self.ports_info = None + self.conf = UserConf() def change_config_option(self, target, parameter, value): """ @@ -78,6 +80,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 @@ -144,8 +154,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): @@ -167,11 +183,27 @@ class Dut(Crb): """ Restore Linux interfaces. """ - Crb.restore_interfaces(self) - - if self.ports_info is not None: - for port in self.ports_info: - self.admin_ports_linux(port['intf'], 'up') + 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, "# ") + else: + self.logger.info("NOT FOUND DRIVER FOR PORT (%s|%s)!!!" % (pci_bus, pci_id)) def setup_memory(self, hugepages=-1): """ @@ -259,7 +291,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. @@ -301,7 +333,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): """ @@ -339,6 +371,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 @@ -381,6 +422,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. @@ -411,8 +501,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 @@ -420,50 +509,10 @@ 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, "# ") - """ - I217 and I218 requires more time to acquire V6 address. - """ - time.sleep(25) - - 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): """ @@ -505,3 +554,22 @@ 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 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 = {} + + for key in ['intf', 'mac', 'numa', 'peer']: + if key in port_cfg: + if key in port and port_cfg[key] != port[key]: + self.logger.warning("CONGGURED %s NOT SAME AS SCANNED!!!" % (key.upper())) + port[key] = port_cfg[key] diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py index 3577eb7..8cb144f 100644 --- a/framework/project_dpdk.py +++ b/framework/project_dpdk.py @@ -236,13 +236,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, '# ') @@ -254,13 +251,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/ssh_connection.py b/framework/ssh_connection.py index 4306162..25f249a 100644 --- a/framework/ssh_connection.py +++ b/framework/ssh_connection.py @@ -40,7 +40,7 @@ class SSHConnection(object): Implement send_expect/copy function upper SSHPexpet module. """ - def __init__(self, host, session_name, password = ''): + def __init__(self, host, session_name, password=''): self.session = SSHPexpect(host, USERNAME, password) self.name = session_name diff --git a/framework/tester.py b/framework/tester.py index 0ebe29a..437d8c4 100644 --- a/framework/tester.py +++ b/framework/tester.py @@ -133,7 +133,7 @@ class Tester(Crb): self.restore_interfaces() self.scan_ports() self.map_available_ports() - if self.ports_map == None or len(self.ports_map) == 0: + if self.ports_map is None or len(self.ports_map) == 0: raise ValueError("ports_map should not be empty, please check all links") def get_local_port(self, remotePort): @@ -179,6 +179,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. @@ -262,6 +280,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