diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 0f97138a6f..89cc7087eb 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -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, diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 6df55bf974..e9360e2f75 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -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