From patchwork Tue Jan 25 02:47:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Dong X-Patchwork-Id: 106448 Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2FE91A04A8; Tue, 25 Jan 2022 03:47:24 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EAAF94280E; Tue, 25 Jan 2022 03:47:23 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mails.dpdk.org (Postfix) with ESMTP id 3550542809 for ; Tue, 25 Jan 2022 03:47:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1643078842; x=1674614842; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=b/OPwWkQ0yQ3KwHxp0hPCDH3lgkyedl/1UPv7gXp2A4=; b=SlTGzCGMdmFq9SHWWJUajl3eOl1a+msbHraIuX35hJMcLrGxpXyNXtD3 wHucnwJIOKtZKGQNbDWOvux5c/o+A4VrsbKv+NXSUj6Fpdr5aMpum8ADo SUwdbsm9jLUR4up0qU2djkPxI9/LiHqtGJCl4fQ5RtaEU4exrNcmmRwmf NIwcsbHhXNemN4EHewBVVKaf3SLdpdGpVXSR8WfgQ2C+1hE2Tmx8Iap8M N/PiXsQ9e9L9cYlHl1xl9jR3hPRoqNib5JPLZKUc0JIDLvdbMweR4CzNV FH6jDAKxGDgFMOzfZSo5PC6o7fxwO2Kb8qasXX/mcejSNSAJbUyyn8URW w==; X-IronPort-AV: E=McAfee;i="6200,9189,10237"; a="233570748" X-IronPort-AV: E=Sophos;i="5.88,313,1635231600"; d="scan'208";a="233570748" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Jan 2022 18:47:20 -0800 X-IronPort-AV: E=Sophos;i="5.88,313,1635231600"; d="scan'208";a="617465735" Received: from shwdenpg197.ccr.corp.intel.com ([10.253.109.35]) by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Jan 2022 18:47:19 -0800 From: DongJunX To: dts@dpdk.org Cc: lijuan.tu@intel.com, qingx.sun@intel.com, junx.dong@intel.com Subject: [V1] framework/*: Modified create_eal_parameters API to support flexibility Date: Tue, 25 Jan 2022 10:47:10 +0800 Message-Id: <20220125024710.1630-1-junx.dong@intel.com> X-Mailer: git-send-email 2.33.1.windows.1 MIME-Version: 1.0 X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org - Refactoring API for easy maintenance. - Format the output format of the continuous cores list. - Append user defined eal parameters. Signed-off-by: DongJunX --- framework/dut.py | 339 ++++++++++++++++++++++++---------------- framework/pmd_output.py | 6 +- 2 files changed, 208 insertions(+), 137 deletions(-) diff --git a/framework/dut.py b/framework/dut.py index dc3fc874..6e722fa5 100644 --- a/framework/dut.py +++ b/framework/dut.py @@ -117,137 +117,209 @@ class Dut(Crb): def create_eal_parameters(self, fixed_prefix=False, socket=-1, **config): """ - generate eal parameters character string - :param config: - :return: eal_str eg:'-c 0xf -a 0000:88:00.0 -a 0000:88:00.1 --file-prefix=dpdk_1112_20190809143420', - if dpdk version < 20.11-rc4, eal_str eg: '-c 0xf -w 0000:88:00.0 --file-prefix=dpdk_1112_20190809143420', - """ - default_cores = '1S/2C/1T' - blank = ' ' - os_type = self.get_os_type() - if config: - # deal with cores - if 'cores' in config: - if type(config['cores']) == list: - core_list = config['cores'] - elif isinstance(config['cores'], str): - if config['cores'] == '' or config['cores'].lower() == 'default': - core_list = self.get_core_list(default_cores) - else: - core_list = self.get_core_list(config['cores'], socket=socket) - else: - core_list = self.get_core_list(default_cores) - - # deal with ports - w_pci_list = [] - if 'ports' in config and len(config['ports']) != 0: - allow_option = '-a' if self.dpdk_version > '20.11.0-rc3' or self.dpdk_version == '20.11.0' else '-w' - for port in config['ports']: - if type(port) == int: - if 'port_options' in config and port in list(config['port_options'].keys()): - port_option = config['port_options'][port] - w_pci_list.append('%s %s,%s' % (allow_option, self.ports_info[port]['pci'], port_option)) + generate eal parameters character string; + :param fixed_prefix: use fixed file-prefix or not, when it is true, + the file-prefix will not be added a timestamp + :param socket: the physical CPU socket index, -1 means no care cpu socket; + :param config: kwargs user defined eal parameters, eg: + sub param cores: set the core info, eg: + cores=[0,1,2,3], + cores='default', + cores='1S/4C/1T', + cores='all'; + sub param ports: set PCI allow list, eg: + ports=['0000:1a:00.0', '0000:1a:00.1'], + ports=[0, 1]; + sub param port_options: set options of port, eg: + port_options={'0000:1a:00.0': "proto_xtr=vlan"}, + port_options={0: "cap=dcf"}; + sub param prefix: set file prefix string, eg: + prefix='vf'; + sub param no_pci: switch of disable PCI bus eg: + no_pci=True; + sub param b_ports: skip probing a PCI device to prevent EAL from using it, eg: + b_ports=['0000:1a:00.0'], + b_ports=[0]; + sub param vdevs: virtual device list, eg: + vdevs=['net_ring0', 'net_ring1']; + sub param other_eal_param: user defined DPDK eal parameters, eg: + other_eal_param='--single-file-segments'; + :return: eal param string, eg: + '-c 0xf -a 0000:88:00.0 --file-prefix=dpdk_1112_20190809143420'; + if DPDK version < 20.11-rc4, eal_str eg: + '-c 0xf -w 0000:88:00.0 --file-prefix=dpdk_1112_20190809143420'; + """ + + class _EalParameter(object): + def __init__(self, _dut, _fixed_prefix, _socket, _config=None): + self.BLANK = ' ' + self.config = _config if _config is not None else dict() + self.os_type = _dut.get_os_type() + self.fixed_prefix = _fixed_prefix + self.socket = _socket + self.dut = _dut + + def _make_cores_param(self): + is_use_default_cores = 'cores' not in self.config \ + or self.config['cores'] == '' \ + or isinstance(self.config['cores'], str) \ + and self.config['cores'].lower() == 'default' + if is_use_default_cores: + default_cores = '1S/2C/1T' + core_list = self.dut.get_core_list(default_cores) + else: + core_list = self._get_cores_from_config() + + def _get_consecutive_cores_range(_cores: list): + _formated_core_list = [] + _tmp_cores_list = list(sorted(map(int, _cores))) + _segment = _tmp_cores_list[:1] + for _core_num in _tmp_cores_list[1:]: + if _core_num - _segment[-1] == 1: + _segment.append(_core_num) else: - w_pci_list.append('%s %s' % (allow_option, self.ports_info[port]['pci'])) - else: - if 'port_options' in config and port in list(config['port_options'].keys()): - port_option = config['port_options'][port] - w_pci_list.append('%s %s,%s' % (allow_option, port, port_option)) + _formated_core_list.append( + f'{_segment[0]}-{_segment[-1]}' if len(_segment) > 1 else f'{_segment[0]}') + _index = _tmp_cores_list.index(_core_num) + _formated_core_list.extend(_get_consecutive_cores_range(_tmp_cores_list[_index:])) + _segment.clear() + break + if len(_segment) > 0: + _formated_core_list.append( + f'{_segment[0]}-{_segment[-1]}' if len(_segment) > 1 else f'{_segment[0]}') + return _formated_core_list + + return f'-l {", ".join(_get_consecutive_cores_range(core_list))}' + + def _make_memory_channels(self): + param_template = '-n {}' + return param_template.format(self.dut.get_memory_channels()) + + def _make_ports_param(self): + if 'ports' in self.config and len(self.config['ports']) != 0: + return self._get_ports_and_wraped_port_with_port_options() + else: + return self._make_default_ports_param() + + def _make_default_ports_param(self): + pci_list = [] + allow_option = self._make_allow_option() + if len(self.dut.ports_info) != 0: + for port_info in self.dut.ports_info: + pci_list.append('%s %s' % (allow_option, port_info['pci'])) + self.dut.logger.info(pci_list) + return ' '.join(pci_list) + + def _make_b_ports_param(self): + b_pci_list = [] + if 'b_ports' in self.config and len(self.config['b_ports']) != 0: + for port in self.config['b_ports']: + if type(port) == int: + b_pci_list.append('-b %s' % self.dut.ports_info[port]['pci']) else: - w_pci_list.append('%s %s' % (allow_option, port)) - w_pci_str = ' '.join(w_pci_list) - - # deal with block ports - b_pci_list = [] - if 'b_ports' in config and len(config['b_ports']) != 0: - for port in config['b_ports']: - if type(port) == int: - b_pci_list.append('-b %s' % self.ports_info[port]['pci']) - else: - b_pci_list = ['-b %s' % pci for pci in config['b_ports']] - b_ports_str = ' '.join(b_pci_list) + b_pci_list = ['-b %s' % pci for pci in self.config['b_ports']] + return ' '.join(b_pci_list) - # deal with no-pci - if 'no_pci' in config: - if config['no_pci'] == True: - no_pci = '--no-pci' + def _make_no_pci_param(self): + if 'no_pci' in self.config and self.config['no_pci'] is True: + return '--no-pci' else: - no_pci = '' - else: - no_pci = '' + return '' - # deal with file prefix - if 'prefix' in config and config['prefix'] != '': - if fixed_prefix == True: - file_prefix = config['prefix'] + def _make_prefix_param(self): + is_prefix_param_available = 'prefix' in self.config and self.config['prefix'] != '' + if is_prefix_param_available: + if self.fixed_prefix is True: + fixed_file_prefix = self.config['prefix'] + else: + fixed_file_prefix = self.config['prefix'] + '_' + self.dut.prefix_subfix else: - file_prefix = config['prefix'] + '_' + self.prefix_subfix - else: - file_prefix = 'dpdk' + '_' + self.prefix_subfix - if file_prefix not in self.prefix_list: - self.prefix_list.append(file_prefix) + fixed_file_prefix = 'dpdk' + '_' + self.dut.prefix_subfix + fixed_file_prefix = '--file-prefix=' + fixed_file_prefix + fixed_file_prefix = self._do_os_handle_with_prefix_param(fixed_file_prefix) + return fixed_file_prefix + + def _make_vdevs_param(self): + if 'vdevs' in self.config and len(self.config['vdevs']) != 0: + _vdevs = ['--vdev ' + vdev for vdev in self.config['vdevs']] + return ' '.join(_vdevs) + else: + return '' + + def _make_share_library_path_param(self): + use_shared_lib = settings.load_global_setting(settings.HOST_SHARED_LIB_SETTING) + shared_lib_path = settings.load_global_setting(settings.HOST_SHARED_LIB_PATH) + if use_shared_lib == 'true' and shared_lib_path and 'Virt' not in str(self.dut): + return ' -d {} '.format(shared_lib_path) + return '' + + def _make_default_force_max_simd_bitwidth_param(self): + rx_mode = settings.load_global_setting(settings.DPDK_RXMODE_SETTING) + build_type = settings.load_global_setting(settings.HOST_BUILD_TYPE_SETTING) + param_template = ' --force-max-simd-bitwidth=%s ' + bitwith_dict = {'novector': '64', 'sse': '128', 'avx2': '256', 'avx512': '512', 'nolimit': '0'} + if build_type == 'meson' and rx_mode in bitwith_dict and \ + 'force-max-simd-bitwidth' not in self.config.get('other_eal_param', ''): + return param_template % bitwith_dict.get(rx_mode) + else: + return '' + + def _get_cores_from_config(self): + if type(self.config['cores']) == list: + return self.config['cores'] + elif isinstance(self.config['cores'], str): + return self.dut.get_core_list(self.config['cores'], socket=self.socket) + + def _get_ports_and_wraped_port_with_port_options(self): + w_pci_list = [] + for port in self.config['ports']: + w_pci_list.append(self._add_port_options_to(port)) + return ' '.join(w_pci_list) + + def _add_port_options_to(self, port): + allow_option = self._make_allow_option() + port_mac_addr = self.dut.ports_info[port]['pci'] if type(port) == int else port + port_param = '%s %s' % (allow_option, port_mac_addr) + port_option = self._get_port_options_from_config(port) + if port_option: + port_param = f'{port_param},{port_option}' + return port_param + + def _get_port_options_from_config(self, port): + if 'port_options' in self.config and port in list(self.config['port_options'].keys()): + return self.config['port_options'][port] + else: + return '' - # deal with vdev - if 'vdevs' in config and len(config['vdevs']) != 0: - vdev = '--vdev ' + ' --vdev '.join(config['vdevs']) - else: - vdev = '' - - if os_type == 'freebsd': - eal_str = '-l ' + ','.join(map(str, core_list)) \ - + blank + '-n %d' % self.get_memory_channels() \ - + blank + w_pci_str \ - + blank + b_ports_str \ - + blank + no_pci \ - + blank + vdev - self.prefix_list = [] - else: - eal_str = '-l ' + ','.join(map(str, core_list)) \ - + blank + '-n %d' % self.get_memory_channels() \ - + blank + w_pci_str \ - + blank + b_ports_str \ - + blank + '--file-prefix=' + file_prefix \ - + blank + no_pci \ - + blank + vdev - else: - allow_option = '-a' if self.dpdk_version > '20.11.0-rc3' or self.dpdk_version == '20.11.0' else '-w' - # get pci from ports_info - pci_list = [] - if len(self.ports_info) != 0: - for port_info in self.ports_info: - pci_list.append('%s %s' % (allow_option, port_info['pci'])) - self.logger.info(pci_list) - pci_str = ' '.join(pci_list) - # default cores '1S/2C/1T' - core_list = self.get_core_list(default_cores) - file_prefix = 'dpdk' + '_' + self.prefix_subfix - self.prefix_list.append(file_prefix) - if os_type == 'freebsd': - eal_str = '-l ' + ','.join(map(str, core_list)) \ - + blank + '-n %d' % self.get_memory_channels() \ - + blank + pci_str - self.prefix_list = [] - else: - eal_str = '-l ' + ','.join(map(str, core_list)) \ - + blank + '-n %d' % self.get_memory_channels() \ - + blank + pci_str \ - + blank + '--file-prefix=' + file_prefix - use_shared_lib = settings.load_global_setting(settings.HOST_SHARED_LIB_SETTING) - shared_lib_path = settings.load_global_setting(settings.HOST_SHARED_LIB_PATH) - if use_shared_lib == 'true' and shared_lib_path and 'Virt' not in str(self): - eal_str = eal_str + ' -d {} '.format(shared_lib_path) - rx_mode = settings.load_global_setting(settings.DPDK_RXMODE_SETTING) - build_type = settings.load_global_setting(settings.HOST_BUILD_TYPE_SETTING) - if build_type == 'meson' and ('other_eal_param' not in config or - 'force-max-simd-bitwidth' not in config['other_eal_param']): - if rx_mode == 'novector': - eal_str = eal_str + ' --force-max-simd-bitwidth=64 ' - elif rx_mode == 'sse': - eal_str = eal_str + ' --force-max-simd-bitwidth=128 ' - elif rx_mode == 'avx2': - eal_str = eal_str + ' --force-max-simd-bitwidth=256 ' - elif rx_mode == 'avx512': - eal_str = eal_str + ' --force-max-simd-bitwidth=512 ' + def _make_allow_option(self): + is_new_dpdk_version = self.dut.dpdk_version > '20.11.0-rc3' or self.dut.dpdk_version == '20.11.0' + return '-a' if is_new_dpdk_version else '-w' + + def _do_os_handle_with_prefix_param(self, file_prefix): + if self.dut.get_os_type() == 'freebsd': + self.dut.prefix_list = [] + file_prefix = '' + else: + self.dut.prefix_list.append(file_prefix) + return file_prefix + + def make_eal_param(self): + _eal_str = self.BLANK.join([self._make_cores_param(), + self._make_memory_channels(), + self._make_ports_param(), + self._make_b_ports_param(), + self._make_prefix_param(), + self._make_no_pci_param(), + self._make_vdevs_param(), + self._make_share_library_path_param(), + self._make_default_force_max_simd_bitwidth_param(), + # append user defined eal parameters + self.config.get('other_eal_param', '') + ]) + return _eal_str + + eal_parameter_creator = _EalParameter(self, fixed_prefix, socket, config) + eal_str = eal_parameter_creator.make_eal_param() return eal_str @@ -556,7 +628,6 @@ class Dut(Crb): total_numa_nodes = len(numa_nodes) self.logger.info(numa_nodes) - force_socket = False if int(hugepages_size) < (1024 * 1024): @@ -578,7 +649,7 @@ class Dut(Crb): arch_huge_pages = hugepages if hugepages > 0 else 2048 if total_huge_pages != arch_huge_pages: - if total_numa_nodes == -1 : + if total_numa_nodes == -1: self.set_huge_pages(arch_huge_pages) else: # before all hugepage average distribution by all socket, @@ -749,7 +820,7 @@ class Dut(Crb): for portid in range(len(self.ports_info)): if self.ports_info[portid]['source'] == 'cfg': if (socket is None or - self.ports_info[portid]['numa'] == -1 or + self.ports_info[portid]['numa'] == -1 or socket == self.ports_info[portid]['numa']): ports.append(portid) return ports @@ -760,7 +831,7 @@ class Dut(Crb): if port_info['type'] == NICS[nic_type]: # match numa or none numa awareness if (socket is None or - port_info['numa'] == -1 or + port_info['numa'] == -1 or socket == port_info['numa']): # port has link, if self.tester.get_local_port(portid) != -1: @@ -913,7 +984,7 @@ class Dut(Crb): ipv6 = "Not connected" out = self.send_expect("ip -family inet address show dev %s | awk '/inet/ { print $2 }'" - % intf, "# ") + % intf, "# ") ipv4 = out.split('/')[0] port_info['ipv6'] = ipv6 @@ -992,7 +1063,7 @@ class Dut(Crb): port_info['port'] = port self.logger.info("DUT cached: [%s %s] %s" % (port_info['pci'], - port_info['type'], port_info['intf'])) + port_info['type'], port_info['intf'])) def scan_ports_uncached(self): """ @@ -1056,7 +1127,7 @@ class Dut(Crb): self.ports_info = [] skipped = RED('Skipped: Unknown/not selected') - + for (pci_bus, pci_id) in self.pci_devices_info: if not settings.accepted_nic(pci_id): @@ -1068,7 +1139,7 @@ class Dut(Crb): bus_id = addr_array[1] devfun_id = addr_array[2] port = GetNicObj(self, domain_id, bus_id, devfun_id) - port.pci_id= pci_id + port.pci_id = pci_id port.name = settings.get_nic_name(pci_id) port.default_driver = settings.get_nic_driver(pci_id) intf = port.get_interface_name() @@ -1095,7 +1166,7 @@ class Dut(Crb): # store the port info to port mapping self.ports_info.append({'port': port, 'pci': pci_str, 'type': pci_id, 'intf': - intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': -1}) + intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': -1}) def setup_virtenv(self, virttype): """ @@ -1145,7 +1216,7 @@ class Dut(Crb): vflist = [] port_driver = port.get_nic_driver() if 'sriov_vfs_pci' in self.ports_info[port_id] and \ - self.ports_info[port_id]['sriov_vfs_pci']: + self.ports_info[port_id]['sriov_vfs_pci']: vflist = self.ports_info[port_id]['sriov_vfs_pci'] else: if not port.get_sriov_vfs_pci(): diff --git a/framework/pmd_output.py b/framework/pmd_output.py index 113e85f6..da2b0de3 100644 --- a/framework/pmd_output.py +++ b/framework/pmd_output.py @@ -139,17 +139,17 @@ class PmdOutput(): config['cores'] = cores if ' -w ' not in eal_param and ' -a ' not in eal_param and ' -b ' not in eal_param \ and 'ports' not in config and 'b_ports' not in config and ' --no-pci ' not in eal_param \ - and ( 'no_pci' not in config or ('no_pci' in config and config['no_pci'] != True)): + and ('no_pci' not in config or ('no_pci' in config and config['no_pci'] != True)): config['ports'] = [self.dut.ports_info[i]['pci'] for i in range(len(self.dut.ports_info))] part_eal_param = self.dut.create_eal_parameters(fixed_prefix=fixed_prefix, socket=socket, **config) - all_eal_param = part_eal_param + ' ' + eal_param + all_eal_param = part_eal_param app_name = self.dut.apps_name['test-pmd'] command = app_name + " %s -- -i %s" % (all_eal_param, param) command = command.replace(' ', ' ') if self.session != self.dut: self.session.send_expect("cd %s" % self.dut.base_dir, "# ") - timeout = config.get('timeout',120) + timeout = config.get('timeout', 120) out = self.session.send_expect(command, expected, timeout) self.command = command # wait 10s to ensure links getting up before test start.