Merge "Fix N3000 FPGA SR-IOV config for split NICs"

This commit is contained in:
Zuul 2020-06-27 22:45:00 +00:00 committed by Gerrit Code Review
commit 18d5985010
3 changed files with 146 additions and 62 deletions

View File

@ -1024,17 +1024,13 @@ def get_sriov_interface_vf_addrs(context, iface, vf_addr_list):
return interface.get_sriov_interface_vf_addrs(context, iface, vf_addr_list)
def get_sriov_config(context, iface):
def get_sriov_vf_config(context, iface, port, vf_config):
"""
Returns an SR-IOV interface config dictionary.
Determine the virtual function config for an SR-IOV interface.
"""
vf_driver = iface['sriov_vf_driver']
vf_config = {}
port = interface.get_sriov_interface_port(context, iface)
if not port:
return {}
# Calculate the VF addresses to assign to a logical VF interface,
# taking into account any upper or lower interfaces.
vf_addr_list = ''
vf_addrs = port.get('sriov_vfs_pci_address', None)
if vf_addrs:
@ -1043,23 +1039,21 @@ def get_sriov_config(context, iface):
context, iface, vf_addr_list)
vf_addr_list = ",".join(vf_addr_list)
if vf_driver:
if constants.SRIOV_DRIVER_TYPE_VFIO in vf_driver:
vf_driver = constants.SRIOV_DRIVER_VFIO_PCI
elif constants.SRIOV_DRIVER_TYPE_NETDEVICE in vf_driver:
if port['sriov_vf_driver'] is not None:
vf_driver = port['sriov_vf_driver']
else:
# Should not happen, but in this case the vf driver
# will be determined by the kernel. That is,
# no explicit bind will be performed by Puppet.
vf_driver = None
# Format the vf addresses as quoted strings in order to prevent
# puppet from treating the address as a time/date value
vf_addrs = [quoted_str(addr.strip())
for addr in vf_addr_list.split(",") if addr]
# Get the user specified VF driver, if any. If the driver is
# None, the driver will be determined by the kernel. That is,
# No explicit bind will be done.
vf_driver = iface.get('sriov_vf_driver', None)
if vf_driver:
if constants.SRIOV_DRIVER_TYPE_VFIO in vf_driver:
vf_driver = constants.SRIOV_DRIVER_VFIO_PCI
elif constants.SRIOV_DRIVER_TYPE_NETDEVICE in vf_driver:
vf_driver = port.get('sriov_vf_driver', None)
for addr in vf_addrs:
vf_config.update({
addr: {
@ -1068,6 +1062,26 @@ def get_sriov_config(context, iface):
}
})
if iface.get('used_by', None):
upper_ifaces = iface['used_by']
for upper_ifname in upper_ifaces:
upper_iface = context['interfaces'][upper_ifname]
get_sriov_vf_config(context, upper_iface, port, vf_config)
def get_sriov_config(context, iface):
"""
Returns an SR-IOV interface config dictionary.
"""
vf_config = {}
if iface['iftype'] != constants.INTERFACE_TYPE_ETHERNET:
return {}
port = interface.get_sriov_interface_port(context, iface)
if not port:
return {}
# Include the desired number of VFs if the device supports SR-IOV
# config via sysfs and is not a sub-interface
num_vfs = None
@ -1075,6 +1089,8 @@ def get_sriov_config(context, iface):
and iface['iftype'] != constants.INTERFACE_TYPE_VF):
num_vfs = iface['sriov_numvfs']
get_sriov_vf_config(context, iface, port, vf_config)
config = {
'ifname': iface['ifname'],
'addr': quoted_str(port['pciaddr'].strip()),

View File

@ -968,6 +968,7 @@ def get_test_ethernet_port(**kw):
'sriov_numvfs': kw.get('sriov_numvfs'),
'sriov_vf_driver': kw.get('sriov_vf_driver'),
'sriov_vf_pdevice_id': kw.get('sriov_vf_pdevice_id'),
'sriov_vfs_pci_address': kw.get('sriov_vfs_pci_address'),
'driver': kw.get('driver'),
'numa_node': kw.get('numa_node', -1)
}

View File

@ -12,7 +12,6 @@ import yaml
from sysinv.common import constants
from sysinv.puppet import interface
from sysinv.puppet import puppet
from sysinv.puppet import quoted_str
from sysinv.objects import base as objbase
from sysinv.tests.db import base as dbbase
@ -153,7 +152,7 @@ class InterfaceTestCaseMixin(base.PuppetTestCaseMixin):
'networktype': networktype,
'imtu': 1500,
'sriov_numvfs': kwargs.get('sriov_numvfs', 0),
'sriov_vf_driver': kwargs.get('sriov_vf_driver', None)}
'sriov_vf_driver': kwargs.get('iface_sriov_vf_driver', None)}
db_interface = dbutils.create_test_interface(**interface)
self.interfaces.append(db_interface)
@ -170,7 +169,7 @@ class InterfaceTestCaseMixin(base.PuppetTestCaseMixin):
'pciaddr': kwargs.get('pciaddr',
'0000:00:00.' + str(port_id + 1)),
'dev_id': kwargs.get('dev_id', 0),
'sriov_vf_driver': kwargs.get('sriov_vf_driver', None),
'sriov_vf_driver': kwargs.get('port_sriov_vf_driver', None),
'sriov_vf_pdevice_id': kwargs.get('sriov_vf_pdevice_id', None),
'sriov_vfs_pci_address': kwargs.get('sriov_vfs_pci_address', '')}
db_port = dbutils.create_test_ethernet_port(**port)
@ -1123,29 +1122,16 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
def _get_sriov_config(self, ifname='default',
vf_driver=constants.SRIOV_DRIVER_TYPE_VFIO,
vf_addrs=None, num_vfs=2,
pf_addr=None, device_id='1572', port_name="eth0"):
if vf_addrs is None:
vf_addrs = []
num_vfs=2, pf_addr=None, device_id='1572',
port_name="eth0", vf_config=None):
if vf_config is None:
vf_config = {}
config = {'ifname': ifname,
'addr': pf_addr if pf_addr else self.port['pciaddr'],
'device_id': device_id,
'num_vfs': num_vfs,
'port_name': port_name,
'vf_config': {}}
if vf_addrs:
for addr in vf_addrs:
vf_config = config['vf_config']
if addr in vf_config.keys():
vf_config.update({addr: {
'addr': addr,
'driver': vf_driver
}})
else:
vf_config[addr] = {
'addr': addr,
'driver': vf_driver
}
'vf_config': vf_config}
return config
@ -1454,60 +1440,141 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
config = self._create_sriov_vf_config(
constants.SRIOV_DRIVER_TYPE_NETDEVICE, 'i40evf', vf_addr_list,
num_vfs)
expected_vf_config = {
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': 'i40evf'},
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': 'i40evf'}
}
expected = self._get_sriov_config(
self.iface['ifname'], 'i40evf',
[quoted_str(vf_addr1),
quoted_str(vf_addr2)],
num_vfs,
ifname=self.iface['ifname'],
vf_driver='i40evf',
num_vfs=num_vfs,
device_id=device_id,
port_name=port_name)
port_name=port_name,
vf_config=expected_vf_config,)
self.assertEqual(expected, config)
def test_get_sriov_config_vfio(self):
vf_addr1 = "0000:81:00.0"
vf_addr2 = "0000:81:01.0"
device_id = '1572'
port_name = 'eth0'
vf_addr_list = "{},{}".format(vf_addr1, vf_addr2)
num_vfs = 4
config = self._create_sriov_vf_config(
constants.SRIOV_DRIVER_TYPE_VFIO, 'i40evf', vf_addr_list,
num_vfs)
expected_vf_config = {
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': 'vfio-pci'},
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': 'vfio-pci'}
}
expected = self._get_sriov_config(
self.iface['ifname'], 'vfio-pci',
[quoted_str(vf_addr1),
quoted_str(vf_addr2)],
num_vfs)
ifname=self.iface['ifname'],
vf_driver='vfio-pci',
num_vfs=num_vfs,
device_id=device_id,
port_name=port_name,
vf_config=expected_vf_config)
self.assertEqual(expected, config)
def test_get_sriov_config_default(self):
vf_addr1 = "0000:81:00.0"
vf_addr2 = "0000:81:01.0"
device_id = '1572'
port_name = 'eth0'
vf_addr_list = "{},{}".format(vf_addr1, vf_addr2)
num_vfs = 1
config = self._create_sriov_vf_config(
None, 'i40evf', vf_addr_list, num_vfs)
expected_vf_config = {
'0000:81:00.0': {'addr': '0000:81:00.0', 'driver': None},
'0000:81:01.0': {'addr': '0000:81:01.0', 'driver': None}
}
expected = self._get_sriov_config(
self.iface['ifname'], None,
[quoted_str(vf_addr1),
quoted_str(vf_addr2)],
num_vfs)
ifname=self.iface['ifname'],
vf_driver=None,
device_id=device_id,
port_name=port_name,
num_vfs=num_vfs,
vf_config=expected_vf_config)
self.assertEqual(expected, config)
def test_get_sriov_config_iftype_vf(self):
port, iface = self._create_ethernet_test(
'sriov1', constants.INTERFACE_CLASS_PCI_SRIOV,
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=2,
sriov_vf_driver=None)
vf = self._create_vf_test("vf1", 1, None, lower_iface=iface)
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=4,
iface_sriov_vf_driver=None,
port_sriov_vf_driver="iavf",
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
self._create_vf_test("vf1", 1, 'vfio', lower_iface=iface)
self._update_context()
config = interface.get_sriov_config(self.context, vf)
config = interface.get_sriov_config(self.context, iface)
expected_vf_config = {
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': None},
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': None},
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'vfio-pci'}
}
expected = self._get_sriov_config(
vf['ifname'], None,
None,
None, pf_addr=port['pciaddr'],
port_name="eth1")
iface['ifname'], None,
num_vfs=4, pf_addr=port['pciaddr'],
port_name="eth1",
vf_config=expected_vf_config)
self.assertEqual(expected, config)
def test_get_sriov_config_iftype_vf_nested(self):
port, iface = self._create_ethernet_test(
'sriov1', constants.INTERFACE_CLASS_PCI_SRIOV,
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=4,
iface_sriov_vf_driver=None,
port_sriov_vf_driver="iavf",
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
vf1 = self._create_vf_test("vf1", 2, 'vfio', lower_iface=iface)
self._create_vf_test("vf2", 1, 'netdevice', lower_iface=vf1)
self._update_context()
config = interface.get_sriov_config(self.context, iface)
expected_vf_config = {
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': None},
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': 'vfio-pci'},
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'iavf'}
}
expected = self._get_sriov_config(
iface['ifname'], None,
num_vfs=4, pf_addr=port['pciaddr'],
port_name="eth1",
vf_config=expected_vf_config)
self.assertEqual(expected, config)
def test_get_sriov_config_iftype_vf_sibling(self):
port, iface = self._create_ethernet_test(
'sriov1', constants.INTERFACE_CLASS_PCI_SRIOV,
constants.NETWORK_TYPE_PCI_SRIOV, sriov_numvfs=4,
iface_sriov_vf_driver=None,
port_sriov_vf_driver="iavf",
sriov_vfs_pci_address="0000:b1:02.0,0000:b1:02.1,0000:b1:02.2,0000:b1:02.3")
self._create_vf_test("vf1", 2, 'vfio', lower_iface=iface)
self._create_vf_test("vf2", 1, 'netdevice', lower_iface=iface)
self._update_context()
config = interface.get_sriov_config(self.context, iface)
expected_vf_config = {
'0000:b1:02.0': {'addr': '0000:b1:02.0', 'driver': None},
'0000:b1:02.1': {'addr': '0000:b1:02.1', 'driver': 'iavf'},
'0000:b1:02.2': {'addr': '0000:b1:02.2', 'driver': 'vfio-pci'},
'0000:b1:02.3': {'addr': '0000:b1:02.3', 'driver': 'vfio-pci'}
}
expected = self._get_sriov_config(
iface['ifname'], None,
num_vfs=4, pf_addr=port['pciaddr'],
port_name="eth1",
vf_config=expected_vf_config)
self.assertEqual(expected, config)
def test_is_a_mellanox_cx3_device_false(self):