Libvirt: gracefully handle non-nic VFs
As part of adding support for bandwidth based scheduling I038867c4094d79ae4a20615ab9c9f9e38fcc2e0a introduced automatic discovery of parent netdev names for PCIe virtual functions. Nova's PCI passthrough support was originally developed for Intel QAT devices and other generic PCI devices. Later support for Neutron based SR-IOV NIC was added. The PCI-SIG SR-IOV specification while most often used by NIC vendors to virtualise a NIC in hardware was designed for devices of any PCIe class. Support for Intel's QAT device and other accelerators like AMD's SRIOV based vGPU have therefore been regressed by the introduction of the new parent_ifname lookup code. This change simply catches the exception that would be raised when pci_utils.get_ifname_by_pci_address is called on generic VFs allowing a graceful fallback to the previous behaviour. Change-Id: Ib3811f828246311d90b0e3ba71c162c03fb8fe5a Closes-Bug: #1821938
This commit is contained in:
parent
357da989c1
commit
e7ae6c65cd
|
@ -15103,6 +15103,28 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
mock_get_net_name.called_once_with(parent_address)
|
||||
mock_dev_lookup.called_once_with(dev_name)
|
||||
|
||||
@mock.patch.object(pci_utils, 'get_ifname_by_pci_address')
|
||||
def test_get_pcidev_info_non_nic(self, mock_get_ifname):
|
||||
self.stub_out('nova.virt.libvirt.host.Host.device_lookup_by_name',
|
||||
lambda self, name: FakeNodeDevice(
|
||||
_fake_NodeDevXml[name]))
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
id = "pci_0000_04_10_7"
|
||||
mock_get_ifname.side_effect = exception.PciDeviceNotFoundById(id=id)
|
||||
actualvf = drvr._get_pcidev_info(id)
|
||||
expect_vf = {
|
||||
"dev_id": id,
|
||||
"address": "0000:04:10.7",
|
||||
"product_id": '1520',
|
||||
"numa_node": None,
|
||||
"vendor_id": '8086',
|
||||
"label": 'label_8086_1520',
|
||||
"dev_type": fields.PciDeviceType.SRIOV_VF,
|
||||
'parent_addr': '0000:04:00.3',
|
||||
}
|
||||
self.assertEqual(expect_vf, actualvf)
|
||||
|
||||
@mock.patch.object(pci_utils, 'get_ifname_by_pci_address',
|
||||
return_value='ens1')
|
||||
def test_get_pcidev_info(self, mock_get_ifname):
|
||||
|
|
|
@ -6040,13 +6040,21 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
fun_cap.device_addrs[0][1],
|
||||
fun_cap.device_addrs[0][2],
|
||||
fun_cap.device_addrs[0][3])
|
||||
return {
|
||||
result = {
|
||||
'dev_type': fields.PciDeviceType.SRIOV_VF,
|
||||
'parent_addr': phys_address,
|
||||
'parent_ifname':
|
||||
pci_utils.get_ifname_by_pci_address(
|
||||
pci_address, pf_interface=True),
|
||||
}
|
||||
parent_ifname = None
|
||||
try:
|
||||
parent_ifname = pci_utils.get_ifname_by_pci_address(
|
||||
pci_address, pf_interface=True)
|
||||
except exception.PciDeviceNotFoundById:
|
||||
# NOTE(sean-k-mooney): we ignore this error as it
|
||||
# is expected when the virtual function is not a NIC.
|
||||
pass
|
||||
if parent_ifname:
|
||||
result['parent_ifname'] = parent_ifname
|
||||
return result
|
||||
|
||||
return {'dev_type': fields.PciDeviceType.STANDARD}
|
||||
|
||||
|
|
Loading…
Reference in New Issue