Skip to content

Commit 78a63c2

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Ignore PCI devices with 32bit domain" into stable/victoria
2 parents e553082 + 90ffc55 commit 78a63c2

File tree

5 files changed

+77
-16
lines changed

5 files changed

+77
-16
lines changed

doc/source/admin/networking.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ A full guide on configuring and using SR-IOV is provided in the
2424
:neutron-doc:`OpenStack Networking service documentation
2525
<admin/config-sriov.html>`
2626

27+
.. note::
28+
29+
Nova only supports PCI addresses where the fields are restricted to the
30+
following maximum value:
31+
32+
* domain - 0xFFFF
33+
* bus - 0xFF
34+
* slot - 0x1F
35+
* function - 0x7
36+
37+
Nova will ignore PCI devices reported by the hypervisor if the address is
38+
outside of these ranges.
2739

2840
NUMA Affinity
2941
-------------

doc/source/admin/pci-passthrough.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ devices with potentially different capabilities.
3737
supported until the 14.0.0 Newton release, see
3838
`bug 1512800 <https://bugs.launchpad.net/nova/+bug/1512880>`_ for details.
3939

40+
.. note::
41+
42+
Nova only supports PCI addresses where the fields are restricted to the
43+
following maximum value:
44+
45+
* domain - 0xFFFF
46+
* bus - 0xFF
47+
* slot - 0x1F
48+
* function - 0x7
49+
50+
Nova will ignore PCI devices reported by the hypervisor if the address is
51+
outside of these ranges.
4052

4153
Configure host (Compute)
4254
------------------------

nova/conf/pci.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,13 @@
116116
117117
``address``
118118
PCI address of the device. Both traditional glob style and regular
119-
expression syntax is supported.
119+
expression syntax is supported. Please note that the address fields are
120+
restricted to the following maximum values:
121+
122+
* domain - 0xFFFF
123+
* bus - 0xFF
124+
* slot - 0x1F
125+
* function - 0x7
120126
121127
``devname``
122128
Device name of the device (for e.g. interface name). Not all PCI devices

nova/pci/manager.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,42 @@ def update_devices_from_hypervisor_resources(self, devices_json):
117117

118118
devices = []
119119
for dev in jsonutils.loads(devices_json):
120-
if self.dev_filter.device_assignable(dev):
121-
devices.append(dev)
120+
try:
121+
if self.dev_filter.device_assignable(dev):
122+
devices.append(dev)
123+
except exception.PciConfigInvalidWhitelist as e:
124+
# The raised exception is misleading as the problem is not with
125+
# the whitelist config but with the host PCI device reported by
126+
# libvirt. The code that matches the host PCI device to the
127+
# withelist spec reuses the WhitelistPciAddress object to parse
128+
# the host PCI device address. That parsing can fail if the
129+
# PCI address has a 32 bit domain. But this should not prevent
130+
# processing the rest of the devices. So we simply skip this
131+
# device and continue.
132+
# Please note that this except block does not ignore the
133+
# invalid whitelist configuration. The whitelist config has
134+
# already been parsed or rejected in case it was invalid. At
135+
# this point the self.dev_filter representes the parsed and
136+
# validated whitelist config.
137+
LOG.debug(
138+
'Skipping PCI device %s reported by the hypervisor: %s',
139+
{k: v for k, v in dev.items()
140+
if k in ['address', 'parent_addr']},
141+
# NOTE(gibi): this is ugly but the device_assignable() call
142+
# uses the PhysicalPciAddress class to parse the PCI
143+
# addresses and that class reuses the code from
144+
# PciAddressSpec that was originally designed to parse
145+
# whitelist spec. Hence the raised exception talks about
146+
# whitelist config. This is misleading as in our case the
147+
# PCI address that we failed to parse came from the
148+
# hypervisor.
149+
# TODO(gibi): refactor the false abstraction to make the
150+
# code reuse clean from the false assumption that we only
151+
# parse whitelist config with
152+
# devspec.PciAddressSpec._set_pci_dev_info()
153+
str(e).replace(
154+
'Invalid PCI devices Whitelist config:', 'The'))
155+
122156
self._set_hvdevs(devices)
123157

124158
@staticmethod

nova/tests/unit/pci/test_manager.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import nova
2323
from nova.compute import vm_states
2424
from nova import context
25-
from nova import exception
2625
from nova import objects
2726
from nova.objects import fields
2827
from nova.pci import manager
@@ -237,7 +236,9 @@ def test_update_devices_from_hypervisor_resources(self, _mock_dev_assign):
237236
tracker.update_devices_from_hypervisor_resources(fake_pci_devs_json)
238237
self.assertEqual(2, len(tracker.pci_devs))
239238

240-
def test_update_devices_from_hypervisor_resources_32bit_domain(self):
239+
@mock.patch("nova.pci.manager.LOG.debug")
240+
def test_update_devices_from_hypervisor_resources_32bit_domain(
241+
self, mock_debug):
241242
self.flags(
242243
group='pci',
243244
passthrough_whitelist=[
@@ -261,17 +262,13 @@ def test_update_devices_from_hypervisor_resources_32bit_domain(self):
261262
fake_pci_devs_json = jsonutils.dumps(fake_pci_devs)
262263
tracker = manager.PciDevTracker(self.fake_context)
263264
# We expect that the device with 32bit PCI domain is ignored
264-
# tracker.update_devices_from_hypervisor_resources(fake_pci_devs_json)
265-
# self.assertEqual(0, len(tracker.pci_devs))
266-
#
267-
# This is the bug 1897528
268-
ex = self.assertRaises(
269-
exception.PciConfigInvalidWhitelist,
270-
tracker.update_devices_from_hypervisor_resources,
271-
fake_pci_devs_json)
272-
self.assertEqual(
273-
'Invalid PCI devices Whitelist config: property domain (10000) is '
274-
'greater than the maximum allowable value (FFFF).', str(ex))
265+
tracker.update_devices_from_hypervisor_resources(fake_pci_devs_json)
266+
self.assertEqual(0, len(tracker.pci_devs))
267+
mock_debug.assert_called_once_with(
268+
'Skipping PCI device %s reported by the hypervisor: %s',
269+
{'address': '10000:00:02.0', 'parent_addr': None},
270+
'The property domain (10000) is greater than the maximum '
271+
'allowable value (FFFF).')
275272

276273
def test_set_hvdev_new_dev(self):
277274
fake_pci_3 = dict(fake_pci, address='0000:00:00.4', vendor_id='v2')

0 commit comments

Comments
 (0)