def restart_ovs_and_pfs_netdevs(): sriov_map = common.get_sriov_map() processutils.execute('/usr/bin/systemctl', 'restart', 'openvswitch') for item in sriov_map: if item['device_type'] == 'pf': if_down_interface(item['name']) if_up_interface(item['name'])
def _get_vf_name_from_map(pf_name, vfid): sriov_map = common.get_sriov_map() for item in sriov_map: if (item['device_type'] == 'vf' and item['device'].get('name') == pf_name and item['device'].get('vfid') == vfid): return item['name']
def update_sriov_pf_map(ifname, numvfs, noop, promisc=None, link_mode='legacy', vdpa=False): if not noop: cur_numvfs = sriov_config.get_numvfs(ifname) if cur_numvfs > 0 and cur_numvfs != numvfs: msg = ("Can't change the numvfs for %s" % ifname) raise sriov_config.SRIOVNumvfsException(msg) sriov_map = common.get_sriov_map() for item in sriov_map: if item['device_type'] == 'pf' and item['name'] == ifname: item['numvfs'] = numvfs item['vdpa'] = vdpa if promisc is not None: item['promisc'] = promisc item['link_mode'] = link_mode break else: new_item = {} new_item['device_type'] = 'pf' new_item['name'] = ifname new_item['numvfs'] = numvfs new_item['vdpa'] = vdpa if promisc is not None: new_item['promisc'] = promisc new_item['link_mode'] = link_mode sriov_map.append(new_item) write_yaml_config(common.SRIOV_CONFIG_FILE, sriov_map)
def _is_vf_by_name(interface_name, check_mapping_file=False): vf_path_check = common.get_dev_path(interface_name, 'physfn') is_sriov_vf = os.path.isdir(vf_path_check) if not is_sriov_vf and check_mapping_file: sriov_map = common.get_sriov_map() for item in sriov_map: if (item['name'] == interface_name and item['device_type'] == 'vf'): is_sriov_vf = True return is_sriov_vf
def _wait_for_vf_creation(pf_name, numvfs): vf_count = 0 pf_config = common.get_sriov_map(pf_name) vdpa = False if len(pf_config): vdpa = pf_config[0].get('vdpa', False) while vf_count < numvfs: try: # wait for 5 seconds after every udev event event = vf_queue.get(True, 5) vf_name = os.path.basename(event["device"]) pf_path = _get_pf_path(event["device"]) logger.debug(f"{event['device']}: Got udev event: {event}") if pf_path: pf_nic = os.listdir(pf_path) # NOTE(dvd): For vDPA devices, the VF event we're interrested # in contains all the VFs. We can also use this to build a dict # to correlate the VF pci address to the PF when creating the # vdpa representator udev rule # # Data structure sample for vDPA: # pf_path: # /sys/devices/pci0000:00/0000:00:02.2/0000:06:01.2/physfn/net # pf_nic: ['enp6s0f1np1_0', 'enp6s0f1np1_1', 'enp6s0f1np1'] # pf_name: enp6s0f1np1 if vf_name not in vf_to_pf and pf_name in pf_nic: vf_to_pf[vf_name] = { 'device': event['device'], 'pf': pf_name } logger.info( f"{pf_name}: VF {vf_name} created" ) vf_count += 1 elif vf_name in vf_to_pf: logger.debug( f"{pf_name}: VF {vf_name} was already created" ) elif vdpa: logger.warning(f"{pf_name}: This PF is not in {pf_path}") else: logger.warning( f"{pf_name}: Unable to parse event {event['device']}" ) elif not vdpa: logger.warning(f"{event['device']}: Unable to find PF") except queue.Empty: logger.info(f"{pf_name}: Timeout in the creation of VFs") return logger.info(f"{pf_name}: Required VFs are created")
def is_partitioned_pf(dev_name: str) -> bool: """Check if any nic-partition(VF) is already used Given a PF device, returns True if any VFs of this device are in-use. """ sriov_map = common.get_sriov_map() for config in sriov_map: devtype = config.get('device_type', None) if devtype == 'vf': name = config.get('device', {}).get('name') vf_name = config.get('name') if dev_name == name: logger.warning(f"{name} has VF({vf_name}) used by host") return True return False
def configure_sriov_vf(): sriov_map = common.get_sriov_map() for item in sriov_map: raise_error = True if item['device_type'] == 'vf': pf_name = item['device']['name'] vfid = item['device']['vfid'] base_cmd = ('ip', 'link', 'set', 'dev', pf_name, 'vf', str(vfid)) logger.info(f"{pf_name}: Configuring settings for VF: {vfid} " f"VF name: {item['name']}") raise_error = True if 'macaddr' in item: cmd = base_cmd + ('mac', item['macaddr']) run_ip_config_cmd(*cmd) if 'vlan_id' in item: vlan_cmd = base_cmd + ('vlan', str(item['vlan_id'])) if 'qos' in item: vlan_cmd = vlan_cmd + ('qos', str(item['qos'])) run_ip_config_cmd(*vlan_cmd) if 'max_tx_rate' in item: cmd = base_cmd + ('max_tx_rate', str(item['max_tx_rate'])) if item['max_tx_rate'] == 0: raise_error = False run_ip_config_cmd_safe(raise_error, *cmd) if 'min_tx_rate' in item: cmd = base_cmd + ('min_tx_rate', str(item['min_tx_rate'])) if item['min_tx_rate'] == 0: raise_error = False run_ip_config_cmd_safe(raise_error, *cmd) if 'spoofcheck' in item: cmd = base_cmd + ('spoofchk', item['spoofcheck']) run_ip_config_cmd(*cmd) if 'state' in item: cmd = base_cmd + ('state', item['state']) run_ip_config_cmd(*cmd) if 'trust' in item: cmd = base_cmd + ('trust', item['trust']) run_ip_config_cmd(*cmd) if 'promisc' in item: run_ip_config_cmd('ip', 'link', 'set', 'dev', item['name'], 'promisc', item['promisc']) if 'driver' in item: common.set_driverctl_override(item['pci_address'], item['driver'])
def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0, spoofcheck=None, trust=None, state=None, macaddr=None, promisc=None, pci_address=None, min_tx_rate=0, max_tx_rate=0, driver=None): sriov_map = common.get_sriov_map() for item in sriov_map: if (item['device_type'] == 'vf' and item['device'].get('name') == pf_name and item['device'].get('vfid') == vfid): item.update( _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state, macaddr, promisc, pci_address, min_tx_rate, max_tx_rate, driver)) _clear_empty_values(item) break else: new_item = {} new_item['device_type'] = 'vf' new_item['device'] = {"name": pf_name, "vfid": vfid} new_item.update( _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state, macaddr, promisc, pci_address, min_tx_rate, max_tx_rate, driver)) _clear_empty_values(new_item) sriov_map.append(new_item) write_yaml_config(common.SRIOV_CONFIG_FILE, sriov_map)
def configure_sriov_pf(execution_from_cli=False, restart_openvswitch=False): observer = udev_monitor_setup() udev_monitor_start(observer) sriov_map = common.get_sriov_map() dpdk_vfs_pcis_list = [] trigger_udev_rule = False # Cleanup the previous config by puppet-tripleo cleanup_puppet_config() if any(item.get('vdpa') for item in sriov_map): common.load_kmods(MLNX5_VDPA_KMODS) vdpa_devices = get_vdpa_vhost_devices() for item in sriov_map: if item['device_type'] == 'pf': _pf_interface_up(item) if item.get('link_mode') == "legacy": # Add a udev rule to configure the VF's when PF's are # released by a guest if not is_partitioned_pf(item['name']): add_udev_rule_for_legacy_sriov_pf(item['name'], item['numvfs']) # When configuring vdpa, we need to configure switchdev before # we create the VFs is_mlnx = common.is_mellanox_interface(item['name']) vdpa = item.get('vdpa') # Configure switchdev mode when vdpa # It has to happen before we set_numvfs if vdpa and is_mlnx: configure_switchdev(item['name']) set_numvfs(item['name'], item['numvfs']) # Configure switchdev, unbind driver and configure vdpa if item.get('link_mode') == "switchdev" and is_mlnx: logger.info(f"{item['name']}: Mellanox card") vf_pcis_list = get_vf_pcis_list(item['name']) for vf_pci in vf_pcis_list: if not vdpa: # For DPDK, we need to unbind the driver _driver_unbind(vf_pci) else: if vf_pci not in vdpa_devices: configure_vdpa_vhost_device(vf_pci) else: logger.info( f"{item['name']}: vDPA device already created " f"for {vf_pci}" ) if vdpa: common.restorecon('/dev/vhost-*') logger.info(f"{item['name']}: Adding udev rules") # Adding a udev rule to make vf-representors unmanaged by # NetworkManager add_udev_rule_to_unmanage_vf_representors_by_nm() # Adding a udev rule to save the sriov_pf name trigger_udev_rule = add_udev_rule_for_sriov_pf(item['name'])\ or trigger_udev_rule trigger_udev_rule = add_udev_rule_for_vf_representors( item['name']) or trigger_udev_rule if not vdpa: # This is used for the sriov_bind_config dpdk_vfs_pcis_list += vf_pcis_list # Configure flow steering mode, default to smfs configure_flow_steering(item['name'], item.get('steering_mode', 'smfs')) # Configure switchdev mode configure_switchdev(item['name']) # Adding a udev rule to rename vf-representors else: trigger_udev_rule = add_udev_rule_for_vdpa_representors( item['name']) or trigger_udev_rule # Moving the sriov-PFs to switchdev mode will put the netdev # interfaces in down state. # In case we are running during initial deployment, # bring the interfaces up. # In case we are running as part of the sriov_config service # after reboot, net config scripts, which run after # sriov_config service will bring the interfaces up. if execution_from_cli: if_up_interface(item['name']) if dpdk_vfs_pcis_list and not vdpa: sriov_bind_pcis_map = {_MLNX_DRIVER: dpdk_vfs_pcis_list} if not execution_from_cli: sriov_bind_config.update_sriov_bind_pcis_map(sriov_bind_pcis_map) else: sriov_bind_config.configure_sriov_bind_service() sriov_bind_config.bind_vfs(sriov_bind_pcis_map) # Trigger udev rules if there is new rules written if trigger_udev_rule: trigger_udev_rules() udev_monitor_stop(observer) if restart_openvswitch: restart_ovs_and_pfs_netdevs()