Provide and use other RCs for mdevs if needed

Now that we have helper methods for knowing which RC we should use
for a specific mdev-supported device, use those RCs for both the
related inventories and for looking at the right allocations.

NOTE(sbauza): Given we no longer provide VGPU resources to a root
Resource Provider since Ussuri, we don't need to support reshapes
for allocations that are "generic mdevs" in the root RP, hence the
reshape methods not being modified.

Change-Id: I0bb93ab0952204e06a50829c4a66b03bddb5be45
Partially-Implemented: blueprint generic-mdevs
This commit is contained in:
Sylvain Bauza
2021-08-02 16:04:15 +02:00
committed by Sean Mooney
parent a543cb23aa
commit 2b847085c8
2 changed files with 54 additions and 12 deletions
+40 -2
View File
@@ -25621,7 +25621,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_existing_mdevs_not_assigned')
def test_allocate_mdevs_with_available_mdevs(self, get_unassigned_mdevs):
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_supported_mdev_resource_classes')
def test_allocate_mdevs_with_available_mdevs(self, get_supported_mdev_rcs,
get_unassigned_mdevs):
self.flags(enabled_mdev_types=['nvidia-11'], group='devices')
allocations = {
uuids.rp1: {
@@ -25630,6 +25633,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
}
}
}
get_supported_mdev_rcs.return_value = set([orc.VGPU])
get_unassigned_mdevs.return_value = set([uuids.mdev1])
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
# Mock the fact update_provider_tree() should have run
@@ -25691,7 +25695,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
'_get_mdev_capable_devices')
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_existing_mdevs_not_assigned')
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_supported_mdev_resource_classes')
def test_allocate_mdevs_with_no_gpu_capacity(self,
get_supported_mdev_rcs,
unallocated_mdevs,
get_mdev_capable_devs,
privsep_create_mdev):
@@ -25703,6 +25710,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
}
}
}
get_supported_mdev_rcs.return_value = set([orc.VGPU])
unallocated_mdevs.return_value = set()
# Mock the fact all possible mediated devices are created and all of
# them being assigned
@@ -25721,7 +25729,12 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
drvr._allocate_mdevs, allocations=allocations)
@mock.patch.object(libvirt_driver.LOG, 'warning')
def test_allocate_mdevs_with_no_idea_of_the_provider(self, mock_warning):
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_supported_mdev_resource_classes')
def test_allocate_mdevs_with_no_idea_of_the_provider(
self, get_supported_mdev_rcs, mock_warning
):
get_supported_mdev_rcs.return_value = set([orc.VGPU])
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
# Mock the fact update_provider_tree() should have run
drvr.provider_tree = self._get_fake_provider_tree_with_vgpu()
@@ -25753,6 +25766,31 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
"ProviderTree roots %(roots)s",
{'name': 'oops_I_did_it_again', 'roots': 'cn'})
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_existing_mdevs_not_assigned')
@mock.patch.object(libvirt_driver.LibvirtDriver,
'_get_supported_mdev_resource_classes')
def test_allocate_mdevs_with_a_different_class(self,
get_supported_mdev_rcs,
get_unassigned_mdevs):
self.flags(enabled_mdev_types=['nvidia-11'], group='devices')
allocations = {
uuids.rp1: {
'resources': {
'CUSTOM_NOTVGPU': 1,
}
}
}
get_supported_mdev_rcs.return_value = set(['CUSTOM_NOTVGPU'])
get_unassigned_mdevs.return_value = set([uuids.mdev1])
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
# Mock the fact update_provider_tree() should have run
drvr.provider_tree = self._get_fake_provider_tree_with_vgpu()
self.assertEqual([uuids.mdev1],
drvr._allocate_mdevs(allocations=allocations))
get_unassigned_mdevs.assert_called_once_with('pci_0000_06_00_0',
['nvidia-11'])
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_vgpu_type_per_pgpu')
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_mediated_devices')
@mock.patch.object(libvirt_driver.LibvirtDriver,
+14 -10
View File
@@ -7813,9 +7813,9 @@ class LibvirtDriver(driver.ComputeDriver):
allocated_mdevs[device.uuid] = guest.uuid
return allocated_mdevs
@staticmethod
def _vgpu_allocations(allocations):
"""Filtering only the VGPU allocations from a list of allocations.
# TODO(sbauza): Rename this method into _mdev_allocations
def _vgpu_allocations(self, allocations):
"""Filtering only the mdev allocations from a list of allocations.
:param allocations: Information about resources allocated to the
instance via placement, of the form returned by
@@ -7824,12 +7824,14 @@ class LibvirtDriver(driver.ComputeDriver):
if not allocations:
# If no allocations, there is no vGPU request.
return {}
RC_VGPU = orc.VGPU
mdev_rcs = self._get_supported_mdev_resource_classes()
vgpu_allocations = {}
for rp in allocations:
res = allocations[rp]['resources']
if RC_VGPU in res and res[RC_VGPU] > 0:
vgpu_allocations[rp] = {'resources': {RC_VGPU: res[RC_VGPU]}}
mdev_resources = {mdev_RC: res[mdev_RC] for mdev_RC in mdev_rcs
if mdev_RC in res and res[mdev_RC] > 0}
if mdev_resources:
vgpu_allocations[rp] = {'resources': mdev_resources}
return vgpu_allocations
def _get_existing_mdevs_not_assigned(self, parent, requested_types=None):
@@ -7913,7 +7915,8 @@ class LibvirtDriver(driver.ComputeDriver):
'while at the moment libvirt only supports one. Only '
'the first allocation will be looked up.')
rp_uuid, alloc = next(iter(vgpu_allocations.items()))
vgpus_asked = alloc['resources'][orc.VGPU]
# We only have one allocation with a supported resource class
vgpus_asked = list(alloc['resources'].values())[0]
# Find if we allocated against a specific pGPU (and then the allocation
# is made against a child RP) or any pGPU (in case the VGPU inventory
@@ -8455,8 +8458,8 @@ class LibvirtDriver(driver.ComputeDriver):
root_node = provider_tree.data(nodename)
return orc.VGPU in root_node.inventory
@staticmethod
def _ensure_pgpu_providers(inventories_dict, provider_tree, nodename):
def _ensure_pgpu_providers(self, inventories_dict, provider_tree,
nodename):
"""Ensures GPU inventory providers exist in the tree for $nodename.
GPU providers are named $nodename_$gpu-device-id, e.g.
@@ -8499,7 +8502,8 @@ class LibvirtDriver(driver.ComputeDriver):
# The VGPU inventory goes on a child provider of the given root
# node, identified by $nodename.
pgpu_inventory = {orc.VGPU: inventory}
mdev_rc = self._get_resource_class_for_device(pgpu_dev_id)
pgpu_inventory = {mdev_rc: inventory}
provider_tree.update_inventory(pgpu_rp_name, pgpu_inventory)
return pgpu_rps