Fix failure in dpdk driver binding with VF during reboot
On a start/reboot, os-net sriov_config.service is run to create VFs for nic-partitioned devices. If vfio-pci driver is bound to any of the VFs, the VF initialisation doesn't occur properly. The VF creation has to be completed before driverctl vfio-pci binding AND all network interface configs. Since the order of sriov_config service or driverctl could not be set due to cyclic dependencies, the driverctl --nosave is used for every reboots for VFs that needs driver override. This is required in case of DPDK - NIC Partitioning. Change-Id: I3b3712eedf6d909f5d65ecbb1763f9dc11b04c31
This commit is contained in:
parent
9c3f1f5804
commit
9ef27075eb
|
@ -57,6 +57,7 @@ DPDK_MAPPING_FILE = '/var/lib/os-net-config/dpdk_mapping.yaml'
|
|||
SRIOV_CONFIG_FILE = '/var/lib/os-net-config/sriov_config.yaml'
|
||||
|
||||
|
||||
_SYS_BUS_PCI_DEV = '/sys/bus/pci/devices'
|
||||
SYS_CLASS_NET = '/sys/class/net'
|
||||
_LOG_FILE = '/var/log/os-net-config.log'
|
||||
MLNX_VENDOR_ID = "0x15b3"
|
||||
|
@ -64,6 +65,10 @@ MLNX_VENDOR_ID = "0x15b3"
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OvsDpdkBindException(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def configure_logger(log_file=False, verbose=False, debug=False):
|
||||
LOG_FORMAT = ('%(asctime)s.%(msecs)03d %(levelname)s '
|
||||
'%(name)s.%(funcName)s %(message)s')
|
||||
|
@ -104,6 +109,14 @@ def get_dev_path(ifname, path=None):
|
|||
return os.path.join(SYS_CLASS_NET, ifname, path)
|
||||
|
||||
|
||||
def get_pci_dev_path(pci_address, path=None):
|
||||
if not path:
|
||||
path = ""
|
||||
elif path.startswith("_"):
|
||||
path = path[1:]
|
||||
return os.path.join(_SYS_BUS_PCI_DEV, pci_address, path)
|
||||
|
||||
|
||||
def get_vendor_id(ifname):
|
||||
try:
|
||||
with open(get_dev_path(ifname, "vendor"), 'r') as f:
|
||||
|
@ -141,6 +154,12 @@ def get_sriov_map(pf_name=None):
|
|||
return sriov_map
|
||||
|
||||
|
||||
def get_dpdk_map():
|
||||
contents = get_file_data(DPDK_MAPPING_FILE)
|
||||
dpdk_map = yaml.safe_load(contents) if contents else []
|
||||
return dpdk_map
|
||||
|
||||
|
||||
def _get_dpdk_mac_address(name):
|
||||
contents = get_file_data(DPDK_MAPPING_FILE)
|
||||
dpdk_map = yaml.safe_load(contents) if contents else []
|
||||
|
@ -171,11 +190,77 @@ def interface_mac(name):
|
|||
raise
|
||||
|
||||
|
||||
def get_interface_driver_by_pci_address(pci_address):
|
||||
try:
|
||||
uevent = get_pci_dev_path(pci_address, 'uevent')
|
||||
with open(uevent, 'r') as f:
|
||||
out = f.read().strip()
|
||||
for line in out.split('\n'):
|
||||
if 'DRIVER' in line:
|
||||
driver = line.split('=')
|
||||
if len(driver) == 2:
|
||||
return driver[1]
|
||||
except IOError:
|
||||
return
|
||||
|
||||
|
||||
def is_mellanox_interface(ifname):
|
||||
vendor_id = get_vendor_id(ifname)
|
||||
return vendor_id == MLNX_VENDOR_ID
|
||||
|
||||
|
||||
def is_vf(pci_address):
|
||||
|
||||
# If DPDK drivers are bound on a VF, then the path common.SYS_CLASS_NET
|
||||
# wouldn't exist. Instead we look for the path
|
||||
# /sys/bus/pci/devices/<PCI addr>/physfn to understand if the device
|
||||
# is actually a VF. This path could be used by VFs not bound with
|
||||
# DPDK drivers as well
|
||||
|
||||
vf_path_check = _SYS_BUS_PCI_DEV + '/%s/physfn' % pci_address
|
||||
is_sriov_vf = os.path.isdir(vf_path_check)
|
||||
return is_sriov_vf
|
||||
|
||||
|
||||
def is_vf_by_name(interface_name, check_mapping_file=False):
|
||||
vf_path_check = 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 = 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 set_driverctl_override(pci_address, driver):
|
||||
if driver is None:
|
||||
logger.info(f"Driver override is not required for device"
|
||||
"{pci_address}")
|
||||
return False
|
||||
iface_driver = get_interface_driver_by_pci_address(pci_address)
|
||||
if iface_driver == driver:
|
||||
logger.info(f"Driver {driver} is already bound to the device"
|
||||
"{pci_address}")
|
||||
return False
|
||||
try:
|
||||
if is_vf(pci_address):
|
||||
out, err = processutils.execute('driverctl', '--nosave',
|
||||
'set-override', pci_address,
|
||||
driver)
|
||||
else:
|
||||
out, err = processutils.execute('driverctl', 'set-override',
|
||||
pci_address, driver)
|
||||
if err:
|
||||
msg = f"Failed to bind dpdk interface {pci_address} err - {err}"
|
||||
raise OvsDpdkBindException(msg)
|
||||
except processutils.ProcessExecutionError:
|
||||
msg = f"Failed to bind interface {pci_address} with dpdk"
|
||||
raise OvsDpdkBindException(msg)
|
||||
return err
|
||||
|
||||
|
||||
def list_kmods(mods: list) -> list:
|
||||
"""Listing Kernel Modules
|
||||
|
||||
|
|
|
@ -1034,7 +1034,8 @@ class LinuxBond(_BaseOpts):
|
|||
macaddr=iface.macaddr, promisc=iface.promisc,
|
||||
pci_address=iface.pci_address,
|
||||
min_tx_rate=iface.min_tx_rate,
|
||||
max_tx_rate=iface.max_tx_rate)
|
||||
max_tx_rate=iface.max_tx_rate,
|
||||
driver=None)
|
||||
|
||||
@staticmethod
|
||||
def from_json(json):
|
||||
|
@ -1120,7 +1121,8 @@ class OvsBond(_BaseOpts):
|
|||
trust=iface.trust, state=iface.state,
|
||||
macaddr=iface.macaddr, promisc=iface.promisc,
|
||||
min_tx_rate=iface.min_tx_rate,
|
||||
max_tx_rate=iface.max_tx_rate)
|
||||
max_tx_rate=iface.max_tx_rate,
|
||||
driver=None)
|
||||
|
||||
@staticmethod
|
||||
def from_json(json):
|
||||
|
@ -1328,7 +1330,7 @@ class OvsDpdkPort(_BaseOpts):
|
|||
self.tx_queue_size = tx_queue_size
|
||||
|
||||
@staticmethod
|
||||
def update_vf_config(iface):
|
||||
def update_vf_config(iface, driver=None):
|
||||
if iface.trust is None:
|
||||
logger.info("Trust is not set for VF %s:%d, defaulting to on"
|
||||
% (iface.device, iface.vfid))
|
||||
|
@ -1340,6 +1342,7 @@ class OvsDpdkPort(_BaseOpts):
|
|||
if iface.promisc is not None:
|
||||
logger.warning("Promisc can't be changed for ovs_dpdk_port")
|
||||
iface.promisc = None
|
||||
logger.info("Overriding the default driver for DPDK")
|
||||
utils.update_sriov_vf_map(iface.device, iface.vfid, iface.name,
|
||||
vlan_id=iface.vlan_id, qos=iface.qos,
|
||||
spoofcheck=iface.spoofcheck,
|
||||
|
@ -1347,7 +1350,8 @@ class OvsDpdkPort(_BaseOpts):
|
|||
macaddr=iface.macaddr, promisc=iface.promisc,
|
||||
pci_address=iface.pci_address,
|
||||
min_tx_rate=iface.min_tx_rate,
|
||||
max_tx_rate=iface.max_tx_rate)
|
||||
max_tx_rate=iface.max_tx_rate,
|
||||
driver=driver)
|
||||
|
||||
@staticmethod
|
||||
def from_json(json):
|
||||
|
@ -1379,7 +1383,7 @@ class OvsDpdkPort(_BaseOpts):
|
|||
# be set in the interface part of DPDK Port
|
||||
members.append(iface)
|
||||
elif isinstance(iface, SriovVF):
|
||||
OvsDpdkPort.update_vf_config(iface)
|
||||
OvsDpdkPort.update_vf_config(iface, driver)
|
||||
members.append(iface)
|
||||
else:
|
||||
msg = 'Unsupported OVS DPDK Port member type'
|
||||
|
@ -1457,6 +1461,8 @@ class SriovVF(_BaseOpts):
|
|||
self.macaddr = macaddr
|
||||
self.promisc = promisc
|
||||
self.pci_address = pci_address
|
||||
self.driver = None
|
||||
|
||||
utils.update_sriov_vf_map(device, self.vfid, name,
|
||||
vlan_id=self.vlan_id,
|
||||
qos=self.qos,
|
||||
|
@ -1467,7 +1473,8 @@ class SriovVF(_BaseOpts):
|
|||
promisc=promisc,
|
||||
pci_address=pci_address,
|
||||
min_tx_rate=min_tx_rate,
|
||||
max_tx_rate=max_tx_rate)
|
||||
max_tx_rate=max_tx_rate,
|
||||
driver=self.driver)
|
||||
|
||||
@staticmethod
|
||||
def get_on_off(config):
|
||||
|
|
|
@ -718,6 +718,9 @@ def configure_sriov_vf():
|
|||
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 parse_opts(argv):
|
||||
|
|
|
@ -1498,8 +1498,8 @@ DOMAIN="openstack.local subdomain.openstack.local"
|
|||
def test_update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=None,
|
||||
qos=None, spoofcheck=None, trust=None,
|
||||
state=None, macaddr=None, promisc=None,
|
||||
pci_address=None,
|
||||
min_tx_rate=0, max_tx_rate=0):
|
||||
pci_address=None, min_tx_rate=0,
|
||||
max_tx_rate=0, driver=None):
|
||||
self.assertEqual(pf_name, 'eth2')
|
||||
self.assertEqual(vfid, 7)
|
||||
self.assertEqual(vlan_id, 0)
|
||||
|
@ -1511,6 +1511,7 @@ DOMAIN="openstack.local subdomain.openstack.local"
|
|||
self.assertEqual(state, None)
|
||||
self.assertEqual(macaddr, None)
|
||||
self.assertEqual(pci_address, '0000:79:10.2')
|
||||
self.assertEqual(driver, None)
|
||||
self.stub_out('os_net_config.utils.update_sriov_vf_map',
|
||||
test_update_sriov_vf_map)
|
||||
|
||||
|
@ -1548,8 +1549,8 @@ NETMASK=255.255.255.0
|
|||
def test_update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=None,
|
||||
qos=None, spoofcheck=None, trust=None,
|
||||
state=None, macaddr=None, promisc=None,
|
||||
pci_address=None,
|
||||
min_tx_rate=0, max_tx_rate=0):
|
||||
pci_address=None, min_tx_rate=0,
|
||||
max_tx_rate=0, driver=None):
|
||||
self.assertEqual(pf_name, 'eth2')
|
||||
self.assertEqual(vf_name, 'eth2_7')
|
||||
self.assertEqual(vfid, 7)
|
||||
|
@ -1563,6 +1564,7 @@ NETMASK=255.255.255.0
|
|||
self.assertEqual(macaddr, "AA:BB:CC:DD:EE:FF")
|
||||
self.assertTrue(promisc)
|
||||
self.assertEqual(pci_address, '0000:80:10.1')
|
||||
self.assertEqual(driver, None)
|
||||
self.stub_out('os_net_config.utils.update_sriov_vf_map',
|
||||
test_update_sriov_vf_map)
|
||||
|
||||
|
@ -1604,8 +1606,8 @@ NETMASK=255.255.255.0
|
|||
def test_update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=None,
|
||||
qos=None, spoofcheck=None, trust=None,
|
||||
state=None, macaddr=None, promisc=None,
|
||||
pci_address=None,
|
||||
min_tx_rate=0, max_tx_rate=0):
|
||||
pci_address=None, min_tx_rate=0,
|
||||
max_tx_rate=0, driver=None):
|
||||
self.assertEqual(pf_name, 'eth2')
|
||||
self.assertEqual(vf_name, 'eth2_7')
|
||||
self.assertEqual(vfid, 7)
|
||||
|
@ -1619,6 +1621,7 @@ NETMASK=255.255.255.0
|
|||
self.assertEqual(macaddr, "AA:BB:CC:DD:EE:FF")
|
||||
self.assertFalse(promisc)
|
||||
self.assertEqual(pci_address, '0000:82:00.2')
|
||||
self.assertEqual(driver, None)
|
||||
self.stub_out('os_net_config.utils.update_sriov_vf_map',
|
||||
test_update_sriov_vf_map)
|
||||
|
||||
|
|
|
@ -687,7 +687,8 @@ class TestBridge(base.TestCase):
|
|||
'vlan_id': 111, 'qos': 1,
|
||||
'min_tx_rate': 0, 'max_tx_rate': 0,
|
||||
'spoofcheck': 'off', 'trust': 'on',
|
||||
'pci_address': '0000:79:10.2'
|
||||
'pci_address': '0000:79:10.2',
|
||||
'driver': 'vfio-pci'
|
||||
}]
|
||||
|
||||
def test_get_vf_devname(device, vfid):
|
||||
|
@ -743,7 +744,8 @@ class TestBridge(base.TestCase):
|
|||
'vlan_id': 111, 'qos': 1,
|
||||
'min_tx_rate': 100, 'max_tx_rate': 500,
|
||||
'spoofcheck': 'off', 'trust': 'off',
|
||||
'pci_address': '0000:79:10.2'
|
||||
'pci_address': '0000:79:10.2',
|
||||
'driver': 'vfio-pci'
|
||||
}]
|
||||
|
||||
def test_get_vf_devname(device, vfid):
|
||||
|
|
|
@ -439,7 +439,7 @@ class TestUtils(base.TestCase):
|
|||
'mac_address': '01:02:03:04:05:06',
|
||||
'driver': 'vfio-pci'}]
|
||||
|
||||
self.stub_out('os_net_config.utils._get_dpdk_map', test_get_dpdk_map)
|
||||
self.stub_out('os_net_config.common.get_dpdk_map', test_get_dpdk_map)
|
||||
pci = utils.get_stored_pci_address('eth1', False)
|
||||
self.assertEqual('0000:00:09.0', pci)
|
||||
|
||||
|
@ -447,7 +447,7 @@ class TestUtils(base.TestCase):
|
|||
def test_get_dpdk_map():
|
||||
return []
|
||||
|
||||
self.stub_out('os_net_config.utils._get_dpdk_map', test_get_dpdk_map)
|
||||
self.stub_out('os_net_config.common.get_dpdk_map', test_get_dpdk_map)
|
||||
pci = utils.get_stored_pci_address('eth1', False)
|
||||
self.assertEqual(None, pci)
|
||||
|
||||
|
@ -492,7 +492,7 @@ class TestUtils(base.TestCase):
|
|||
test_get_dpdk_mac_address)
|
||||
try:
|
||||
utils.bind_dpdk_interfaces('nic2', 'vfio-pci', False)
|
||||
except utils.OvsDpdkBindException:
|
||||
except common.OvsDpdkBindException:
|
||||
self.fail("Received OvsDpdkBindException unexpectedly")
|
||||
|
||||
def test_bind_dpdk_interfaces_fail(self):
|
||||
|
@ -509,7 +509,7 @@ class TestUtils(base.TestCase):
|
|||
self.stub_out('os_net_config.common._get_dpdk_mac_address',
|
||||
test_get_dpdk_mac_address)
|
||||
|
||||
self.assertRaises(utils.OvsDpdkBindException,
|
||||
self.assertRaises(common.OvsDpdkBindException,
|
||||
utils.bind_dpdk_interfaces, 'eth1', 'vfio-pci',
|
||||
False)
|
||||
|
||||
|
@ -528,13 +528,13 @@ class TestUtils(base.TestCase):
|
|||
'mac_address': '01:02:03:04:05:06',
|
||||
'driver': 'vfio-pci'}]
|
||||
|
||||
self.stub_out('os_net_config.utils._get_dpdk_map', test_get_dpdk_map)
|
||||
self.stub_out('os_net_config.common.get_dpdk_map', test_get_dpdk_map)
|
||||
self.stub_out('oslo_concurrency.processutils.execute', test_execute)
|
||||
self.stub_out('os_net_config.utils_get_dpdk_mac_address',
|
||||
test_get_dpdk_mac_address)
|
||||
try:
|
||||
utils.bind_dpdk_interfaces('eth1', 'vfio-pci', False)
|
||||
except utils.OvsDpdkBindException:
|
||||
except common.OvsDpdkBindException:
|
||||
self.fail("Received OvsDpdkBindException unexpectedly")
|
||||
|
||||
def test_bind_dpdk_interfaces_fail_invalid_device(self):
|
||||
|
@ -552,14 +552,14 @@ class TestUtils(base.TestCase):
|
|||
'mac_address': '01:02:03:04:05:06',
|
||||
'driver': 'vfio-pci'}]
|
||||
|
||||
self.stub_out('os_net_config.utils_get_dpdk_map',
|
||||
self.stub_out('os_net_config.common.get_dpdk_map',
|
||||
test_get_dpdk_map)
|
||||
self.stub_out('oslo_concurrency.processutils.execute',
|
||||
test_execute)
|
||||
self.stub_out('os_net_config.utils._get_dpdk_mac_address',
|
||||
test_get_dpdk_mac_address)
|
||||
|
||||
self.assertRaises(utils.OvsDpdkBindException,
|
||||
self.assertRaises(common.OvsDpdkBindException,
|
||||
utils.bind_dpdk_interfaces, 'eth2', 'vfio-pci',
|
||||
False)
|
||||
|
||||
|
@ -570,7 +570,7 @@ class TestUtils(base.TestCase):
|
|||
self.stub_out('os_net_config.utils.logger.info', mocked_logger)
|
||||
try:
|
||||
utils.bind_dpdk_interfaces('eth1', 'vfio-pci', False)
|
||||
except utils.OvsDpdkBindException:
|
||||
except common.OvsDpdkBindException:
|
||||
self.fail("Received OvsDpdkBindException unexpectedly")
|
||||
msg = "Driver (vfio-pci) is already bound to the device (eth1)"
|
||||
mocked_logger.assert_called_with(msg)
|
||||
|
@ -643,8 +643,8 @@ class TestUtils(base.TestCase):
|
|||
tmpdir = tempfile.mkdtemp()
|
||||
self.stub_out('os_net_config.common.SYS_CLASS_NET', tmpdir)
|
||||
tmp_pci_dir = tempfile.mkdtemp()
|
||||
self.stub_out('os_net_config.utils._SYS_BUS_PCI_DEV', tmp_pci_dir)
|
||||
physfn_path = utils._SYS_BUS_PCI_DEV + '/0000:05:01.1/physfn'
|
||||
self.stub_out('os_net_config.common._SYS_BUS_PCI_DEV', tmp_pci_dir)
|
||||
physfn_path = common._SYS_BUS_PCI_DEV + '/0000:05:01.1/physfn'
|
||||
os.makedirs(physfn_path)
|
||||
|
||||
def test_is_available_nic(interface_name, check_active):
|
||||
|
@ -684,8 +684,8 @@ class TestUtils(base.TestCase):
|
|||
tmpdir = tempfile.mkdtemp()
|
||||
self.stub_out('os_net_config.common.SYS_CLASS_NET', tmpdir)
|
||||
tmp_pci_dir = tempfile.mkdtemp()
|
||||
self.stub_out('os_net_config.utils._SYS_BUS_PCI_DEV', tmp_pci_dir)
|
||||
physfn_path = utils._SYS_BUS_PCI_DEV + '/0000:05:01.1/physfn'
|
||||
self.stub_out('os_net_config.common._SYS_BUS_PCI_DEV', tmp_pci_dir)
|
||||
physfn_path = common._SYS_BUS_PCI_DEV + '/0000:05:01.1/physfn'
|
||||
os.makedirs(physfn_path)
|
||||
|
||||
def test_is_available_nic(interface_name, check_active):
|
||||
|
@ -914,7 +914,7 @@ dpdk {
|
|||
'mac_address': '01:02:03:04:05:06',
|
||||
'driver': 'vfio-pci'}]
|
||||
|
||||
self.stub_out('os_net_config.utils._get_dpdk_map', test_get_dpdk_map)
|
||||
self.stub_out('os_net_config.common.get_dpdk_map', test_get_dpdk_map)
|
||||
|
||||
def test_execute(name, *args, **kwargs):
|
||||
return None, None
|
||||
|
|
|
@ -26,7 +26,6 @@ from os_net_config import sriov_config
|
|||
from oslo_concurrency import processutils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
_SYS_BUS_PCI_DEV = '/sys/bus/pci/devices'
|
||||
# sriov_config service shall be created and enabled so that the various
|
||||
# SR-IOV PF and VF configurations shall be done during reboot as well using
|
||||
# sriov_config.py installed in path /usr/bin/os-net-config-sriov
|
||||
|
@ -34,14 +33,14 @@ _SRIOV_CONFIG_SERVICE_FILE = "/etc/systemd/system/sriov_config.service"
|
|||
_SRIOV_CONFIG_DEVICE_CONTENT = """[Unit]
|
||||
Description=SR-IOV numvfs configuration
|
||||
After=systemd-udev-settle.service openibd.service
|
||||
Before=openvswitch.service
|
||||
Before=network-pre.target openvswitch.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/os-net-config-sriov
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=basic.target
|
||||
"""
|
||||
|
||||
# VPP startup operational configuration file. The content of this file will
|
||||
|
@ -53,10 +52,6 @@ class InvalidInterfaceException(ValueError):
|
|||
pass
|
||||
|
||||
|
||||
class OvsDpdkBindException(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
class VppException(ValueError):
|
||||
pass
|
||||
|
||||
|
@ -110,31 +105,6 @@ def is_real_nic(interface_name):
|
|||
return False
|
||||
|
||||
|
||||
def _is_vf(pci_address):
|
||||
|
||||
# If DPDK drivers are bound on a VF, then the path common.SYS_CLASS_NET
|
||||
# wouldn't exist. Instead we look for the path
|
||||
# /sys/bus/pci/devices/<PCI addr>/physfn to understand if the device
|
||||
# is actually a VF. This path could be used by VFs not bound with
|
||||
# DPDK drivers as well
|
||||
|
||||
vf_path_check = _SYS_BUS_PCI_DEV + '/%s/physfn' % pci_address
|
||||
is_sriov_vf = os.path.isdir(vf_path_check)
|
||||
return is_sriov_vf
|
||||
|
||||
|
||||
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 _is_available_nic(interface_name, check_active=True):
|
||||
try:
|
||||
if interface_name == 'lo':
|
||||
|
@ -155,7 +125,7 @@ def _is_available_nic(interface_name, check_active=True):
|
|||
# the nic numbering. All the VFs will have a reference to the PF with
|
||||
# directory name as 'physfn', if this directory is present it should be
|
||||
# ignored.
|
||||
if _is_vf_by_name(interface_name):
|
||||
if common.is_vf_by_name(interface_name):
|
||||
return False
|
||||
|
||||
# nic is available
|
||||
|
@ -210,9 +180,9 @@ def _ordered_nics(check_active):
|
|||
# If the DPDK drivers are bound to a VF, the same needs
|
||||
# to be skipped for the NIC ordering
|
||||
nic = item['name']
|
||||
if _is_vf(item['pci_address']):
|
||||
if common.is_vf(item['pci_address']):
|
||||
logger.info("%s is a VF, skipping it for NIC ordering" % nic)
|
||||
elif _is_vf_by_name(nic, True):
|
||||
elif common.is_vf_by_name(nic, True):
|
||||
logger.info("%s is a VF, skipping it for NIC ordering" % nic)
|
||||
elif _is_embedded_nic(nic):
|
||||
logger.info("%s is an embedded DPDK bound nic" % nic)
|
||||
|
@ -247,7 +217,7 @@ def bind_dpdk_interfaces(ifname, driver, noop):
|
|||
if common.is_mellanox_interface(ifname) and 'vfio-pci' in driver:
|
||||
msg = ("For Mellanox NIC %s, the default driver vfio-pci "
|
||||
"needs to be overridden" % ifname)
|
||||
raise OvsDpdkBindException(msg)
|
||||
raise common.OvsDpdkBindException(msg)
|
||||
|
||||
iface_driver = get_interface_driver(ifname)
|
||||
if iface_driver == driver:
|
||||
|
@ -264,33 +234,23 @@ def bind_dpdk_interfaces(ifname, driver, noop):
|
|||
processutils.execute('modprobe', 'vfio-pci')
|
||||
except processutils.ProcessExecutionError:
|
||||
msg = "Failed to modprobe vfio-pci module"
|
||||
raise OvsDpdkBindException(msg)
|
||||
raise common.OvsDpdkBindException(msg)
|
||||
|
||||
mac_address = common.interface_mac(ifname)
|
||||
vendor_id = common.get_vendor_id(ifname)
|
||||
try:
|
||||
out, err = processutils.execute('driverctl', 'set-override',
|
||||
pci_address, driver)
|
||||
if err:
|
||||
msg = "Failed to bind dpdk interface err - %s" % err
|
||||
raise OvsDpdkBindException(msg)
|
||||
else:
|
||||
_update_dpdk_map(ifname, pci_address, mac_address, driver)
|
||||
# Not like other nics, beacause mellanox nics keep the
|
||||
# interface after binding it to dpdk, so we are adding
|
||||
# ethtool command with 10 attempts after binding the driver
|
||||
# just to make sure that the interface is initialized
|
||||
# successfully in order not to fail in each of this cases:
|
||||
# - get_dpdk_devargs() in case of OvsDpdkPort and
|
||||
# OvsDpdkBond.
|
||||
# - bind_dpdk_interface() in case of OvsDpdkBond.
|
||||
if vendor_id == common.MLNX_VENDOR_ID:
|
||||
processutils.execute('ethtool', '-i', ifname,
|
||||
attempts=10)
|
||||
|
||||
except processutils.ProcessExecutionError:
|
||||
msg = "Failed to bind interface %s with dpdk" % ifname
|
||||
raise OvsDpdkBindException(msg)
|
||||
err = common.set_driverctl_override(pci_address, driver)
|
||||
if not err:
|
||||
_update_dpdk_map(ifname, pci_address, mac_address, driver)
|
||||
# Not like other nics, beacause mellanox nics keep the
|
||||
# interface after binding it to dpdk, so we are adding
|
||||
# ethtool command with 10 attempts after binding the driver
|
||||
# just to make sure that the interface is initialized
|
||||
# successfully in order not to fail in each of this cases:
|
||||
# - get_dpdk_devargs() in case of OvsDpdkPort and
|
||||
# OvsDpdkBond.
|
||||
# - bind_dpdk_interface() in case of OvsDpdkBond.
|
||||
if vendor_id == common.MLNX_VENDOR_ID:
|
||||
processutils.execute('ethtool', '-i', ifname, attempts=10)
|
||||
else:
|
||||
# Check if the pci address is already fetched and stored.
|
||||
# If the pci address could not be fetched from dpdk_mapping.yaml
|
||||
|
@ -298,7 +258,7 @@ def bind_dpdk_interfaces(ifname, driver, noop):
|
|||
# available nor bound with dpdk.
|
||||
if not get_stored_pci_address(ifname, noop):
|
||||
msg = "Interface %s cannot be found" % ifname
|
||||
raise OvsDpdkBindException(msg)
|
||||
raise common.OvsDpdkBindException(msg)
|
||||
else:
|
||||
logger.info('Interface %(name)s bound to DPDK driver %(driver)s '
|
||||
'using driverctl command' %
|
||||
|
@ -327,7 +287,7 @@ def get_pci_address(ifname, noop):
|
|||
|
||||
def get_stored_pci_address(ifname, noop):
|
||||
if not noop:
|
||||
dpdk_map = _get_dpdk_map()
|
||||
dpdk_map = common.get_dpdk_map()
|
||||
for dpdk_nic in dpdk_map:
|
||||
if dpdk_nic['name'] == ifname:
|
||||
return dpdk_nic['pci_address']
|
||||
|
@ -376,7 +336,7 @@ def get_dpdk_devargs(ifname, noop):
|
|||
# in dpdk_mapping.yaml file, so we need to get their pci
|
||||
# address with ethtool.
|
||||
dpdk_devargs = get_pci_address(ifname, noop)
|
||||
elif _is_vf_by_name(ifname):
|
||||
elif common.is_vf_by_name(ifname):
|
||||
# For Mellanox devices the VFs bound with DPDK shall
|
||||
# be treated the same as VFs of other devices
|
||||
dpdk_devargs = get_pci_address(ifname, noop)
|
||||
|
@ -396,7 +356,7 @@ def get_dpdk_devargs(ifname, noop):
|
|||
# is stored persistently in DPDK_MAPPING_FILE and is used to for nic numbering
|
||||
# on subsequent runs of os-net-config.
|
||||
def _update_dpdk_map(ifname, pci_address, mac_address, driver):
|
||||
dpdk_map = _get_dpdk_map()
|
||||
dpdk_map = common.get_dpdk_map()
|
||||
for item in dpdk_map:
|
||||
if item['pci_address'] == pci_address:
|
||||
item['name'] = ifname
|
||||
|
@ -414,12 +374,6 @@ def _update_dpdk_map(ifname, pci_address, mac_address, driver):
|
|||
write_yaml_config(common.DPDK_MAPPING_FILE, dpdk_map)
|
||||
|
||||
|
||||
def _get_dpdk_map():
|
||||
contents = common.get_file_data(common.DPDK_MAPPING_FILE)
|
||||
dpdk_map = yaml.safe_load(contents) if contents else []
|
||||
return dpdk_map
|
||||
|
||||
|
||||
def update_sriov_pf_map(ifname, numvfs, noop, promisc=None,
|
||||
link_mode='legacy', vdpa=False, steering_mode=None):
|
||||
if not noop:
|
||||
|
@ -455,7 +409,7 @@ def update_sriov_pf_map(ifname, numvfs, noop, promisc=None,
|
|||
|
||||
|
||||
def _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state, macaddr,
|
||||
promisc, pci_address, min_tx_rate, max_tx_rate):
|
||||
promisc, pci_address, min_tx_rate, max_tx_rate, driver):
|
||||
vf_configs = {}
|
||||
vf_configs['name'] = vf_name
|
||||
if vlan_id != 0:
|
||||
|
@ -474,6 +428,8 @@ def _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state, macaddr,
|
|||
vf_configs['macaddr'] = macaddr
|
||||
vf_configs['promisc'] = promisc
|
||||
vf_configs['pci_address'] = pci_address
|
||||
if driver:
|
||||
vf_configs['driver'] = driver
|
||||
return vf_configs
|
||||
|
||||
|
||||
|
@ -486,7 +442,7 @@ def _clear_empty_values(vf_config):
|
|||
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):
|
||||
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
|
||||
|
@ -494,7 +450,8 @@ def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
|||
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))
|
||||
pci_address, min_tx_rate, max_tx_rate,
|
||||
driver))
|
||||
_clear_empty_values(item)
|
||||
break
|
||||
else:
|
||||
|
@ -503,7 +460,8 @@ def update_sriov_vf_map(pf_name, vfid, vf_name, vlan_id=0, qos=0,
|
|||
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))
|
||||
pci_address, min_tx_rate, max_tx_rate,
|
||||
driver))
|
||||
_clear_empty_values(new_item)
|
||||
sriov_map.append(new_item)
|
||||
|
||||
|
|
Loading…
Reference in New Issue