Merge "Handle N3000 FPGA reset"

This commit is contained in:
Zuul 2020-06-24 16:39:00 +00:00 committed by Gerrit Code Review
commit 550ec8af8b
7 changed files with 77 additions and 5 deletions

View File

@ -354,6 +354,11 @@ def _check_field(field):
def _check_device_sriov(device, host):
sriov_update = False
if (device['pdevice_id'] == dconstants.PCI_DEVICE_ID_FPGA_INTEL_5GNR_FEC_PF and
host.invprovision != constants.PROVISIONED):
raise wsme.exc.ClientSideError(_("Cannot configure device %s "
"until host %s is unlocked for the first time." %
(device['uuid'], host.hostname)))
if (device['pdevice_id'] not in dconstants.SRIOV_ENABLED_DEVICE_IDS and
'sriov_numvfs' in device.keys() and device['sriov_numvfs']):

View File

@ -8,6 +8,7 @@
import collections
import copy
import re
from oslo_log import log
from sysinv.common import constants
@ -124,6 +125,21 @@ def get_sriov_interface_port(context, iface):
return get_interface_port(context, iface)
def get_sriov_interface_device_id(context, iface):
"""
Determine the underlying PCI device id of the SR-IOV interface.
"""
# The device id can be found by inspecting the '[xxxx]' at the
# end of the port's pdevice field
device_id = None
port = get_sriov_interface_port(context, iface)
if port:
device_id = re.search(r'\[([0-9a-fA-F]{1,4})\]$', port['pdevice'])
if device_id:
device_id = device_id.group(1)
return device_id
def get_sriov_interface_vf_addrs(context, iface, vf_addr_list):
"""
Determine the virtual function addresses of SR-IOV interface,

View File

@ -66,6 +66,9 @@ class DevicePuppet(base.BasePuppet):
device_config = {}
vf_config = {}
for device in fpga_fec_devices:
if not device.get('driver', None) or not device.get('sriov_numvfs', None):
continue
name = 'pci-%s' % device.pciaddr
# Format the vf addresses as quoted strings in order to prevent
@ -91,7 +94,8 @@ class DevicePuppet(base.BasePuppet):
device.pciaddr: {
'num_vfs': device['sriov_numvfs'],
'addr': quoted_str(device['pciaddr'].strip()),
'driver': device['driver']
'driver': device['driver'],
'device_id': device['pdevice_id']
}
}
device_config = {

View File

@ -1009,6 +1009,13 @@ def get_sriov_interface_port(context, iface):
return interface.get_sriov_interface_port(context, iface)
def get_sriov_interface_device_id(context, iface):
"""
Determine the underlying PCI device id of the SR-IOV interface.
"""
return interface.get_sriov_interface_device_id(context, iface)
def get_sriov_interface_vf_addrs(context, iface, vf_addr_list):
"""
Determine the virtual function addresses of SR-IOV interface,
@ -1072,6 +1079,8 @@ def get_sriov_config(context, iface):
'ifname': iface['ifname'],
'addr': quoted_str(port['pciaddr'].strip()),
'num_vfs': num_vfs,
'device_id': interface.get_sriov_interface_device_id(context, iface),
'port_name': port['name'],
'vf_config': vf_config
}
return config

View File

@ -57,7 +57,7 @@ class TestDevice(base.FunctionalTest, dbbase.BaseHostTestCase):
self.controller = host
else:
self.worker = host
return
return host
def _create_device(self, **kw):
device = dbutils.create_test_pci_device(**kw)
@ -394,3 +394,23 @@ class TestPatchDevice(TestDevice):
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
self.assertIn('attribute restricted', response.json['error_message'])
def test_device_modify_fec_device_unprovisioned(self):
host = self._create_host(constants.CONTROLLER,
subfunction=constants.WORKER,
admin=constants.ADMIN_LOCKED,
invprovision="provisioning")
self.pci_device = dbutils.create_test_pci_device(
host_id=host.id,
pclass_id=dconstants.PCI_DEVICE_CLASS_FPGA,
pdevice_id=dconstants.PCI_DEVICE_ID_FPGA_INTEL_5GNR_FEC_PF,
sriov_totalvfs=8,
sriov_numvfs=2)
response = self.patch_dict_json(
'%s' % self._get_path(self.pci_device['uuid']),
sriov_numvfs=-1,
expect_errors=True)
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
self.assertIn('is unlocked for the first time', response.json['error_message'])

View File

@ -961,6 +961,7 @@ def get_test_ethernet_port(**kw):
'interface_id': kw.get('interface_id'),
'interface_uuid': kw.get('interface_uuid'),
'pciaddr': kw.get('pciaddr'),
'pdevice': kw.get('pdevice'),
'dpdksupport': kw.get('dpdksupport'),
'dev_id': kw.get('dev_id'),
'sriov_totalvfs': kw.get('sriov_totalvfs'),

View File

@ -166,6 +166,7 @@ class InterfaceTestCaseMixin(base.PuppetTestCaseMixin):
'mac': interface['imac'],
'driver': kwargs.get('driver', 'ixgbe'),
'dpdksupport': kwargs.get('dpdksupport', True),
'pdevice': "Ethernet Controller X710 for 10GbE SFP+ [1572]",
'pciaddr': kwargs.get('pciaddr',
'0000:00:00.' + str(port_id + 1)),
'dev_id': kwargs.get('dev_id', 0),
@ -787,6 +788,15 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
self.context, self.iface)
self.assertIsNone(classifier)
def test_get_sriov_interface_device_id(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)
self._update_context()
value = interface.get_sriov_interface_device_id(self.context, iface)
self.assertEqual(value, '1572')
def test_get_sriov_interface_port(self):
port, iface = self._create_ethernet_test(
'sriov1', constants.INTERFACE_CLASS_PCI_SRIOV,
@ -1114,12 +1124,14 @@ 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):
pf_addr=None, device_id='1572', port_name="eth0"):
if vf_addrs is None:
vf_addrs = []
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:
@ -1434,6 +1446,8 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
def test_get_sriov_config_netdevice(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 = 2
@ -1444,7 +1458,9 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
self.iface['ifname'], 'i40evf',
[quoted_str(vf_addr1),
quoted_str(vf_addr2)],
num_vfs)
num_vfs,
device_id=device_id,
port_name=port_name)
self.assertEqual(expected, config)
def test_get_sriov_config_vfio(self):
@ -1490,7 +1506,8 @@ class InterfaceTestCase(InterfaceTestCaseMixin, dbbase.BaseHostTestCase):
expected = self._get_sriov_config(
vf['ifname'], None,
None,
None, pf_addr=port['pciaddr'])
None, pf_addr=port['pciaddr'],
port_name="eth1")
self.assertEqual(expected, config)
def test_is_a_mellanox_cx3_device_false(self):