diff options
author | Jianghua Wang <jianghua.wang@citrix.com> | 2017-10-30 05:07:31 +0000 |
---|---|---|
committer | Jianghua Wang <jianghua.wang@citrix.com> | 2017-11-28 00:30:15 -0800 |
commit | 5b83ad63223df5b7ef477d4cdf0fb605dd1bed04 (patch) | |
tree | d0e2fc974026a547fd03755ab2623694890daea4 /nova | |
parent | 6d2cd197bc312ac4c7b1879f4e64fecc14bb0147 (diff) | |
download | nova-5b83ad63223df5b7ef477d4cdf0fb605dd1bed04.tar.gz |
XenAPI: provide vGPU inventory in compute node
This commit is to create inventory data for virtual GPU(vGPU)
basing on the host_stats reported by XenAPI. The final target
is to create child resource providers under the compute node
for each GPU group (XenAPI manages the same type of physical
GPU in one GPU group), so that we can support multiple GPUs which
have different traits. Then users can consume vGPU from different
resource providers(representing GPU groups) basing on specific
traits. But at the moment, the nested resource provider is still
in progress of development. So the decision is to firstly implement
a simple vGPU feature by including vGPU resource in compute node's
inventory.
Change-Id: Iba4fcb82dd18e8c1f22d0ce3358078c5263c77dc
blueprint: add-support-for-vgpu
Diffstat (limited to 'nova')
-rw-r--r-- | nova/tests/unit/virt/xenapi/test_driver.py | 48 | ||||
-rw-r--r-- | nova/virt/xenapi/driver.py | 25 |
2 files changed, 73 insertions, 0 deletions
diff --git a/nova/tests/unit/virt/xenapi/test_driver.py b/nova/tests/unit/virt/xenapi/test_driver.py index 2ba9235998..4cc2c83332 100644 --- a/nova/tests/unit/virt/xenapi/test_driver.py +++ b/nova/tests/unit/virt/xenapi/test_driver.py @@ -266,6 +266,12 @@ class XenAPIDriverTestCase(stubs.XenAPITestBaseNoDB): 'max_unit': 5, 'step_size': 1, }, + obj_fields.ResourceClass.VGPU: { + 'total': 7, + 'min_unit': 1, + 'max_unit': 1, + 'step_size': 1, + }, } mock_get_stats.side_effect = self.host_stats @@ -274,3 +280,45 @@ class XenAPIDriverTestCase(stubs.XenAPITestBaseNoDB): mock_get_stats.assert_called_once_with(refresh=True) self.assertEqual(expected_inv, inv) + + @mock.patch.object(host.HostState, 'get_host_stats') + def test_get_inventory_no_vgpu(self, mock_get_stats): + # Test when there are no vGPU resources in the inventory. + host_stats = self.host_stats() + host_stats.update(vgpu_stats={}) + mock_get_stats.return_value = host_stats + + drv = self._get_driver() + inv = drv.get_inventory(mock.sentinel.nodename) + + # check if the inventory data does NOT contain VGPU. + self.assertNotIn(obj_fields.ResourceClass.VGPU, inv) + + def test_get_vgpu_total_single_grp(self): + # Test when only one group included in the host_stats. + vgpu_stats = { + 'grp_uuid_1': { + 'total': 7 + } + } + + drv = self._get_driver() + vgpu_total = drv._get_vgpu_total(vgpu_stats) + + self.assertEqual(7, vgpu_total) + + def test_get_vgpu_total_multiple_grps(self): + # Test when multiple groups included in the host_stats. + vgpu_stats = { + 'grp_uuid_1': { + 'total': 7 + }, + 'grp_uuid_2': { + 'total': 4 + } + } + + drv = self._get_driver() + vgpu_total = drv._get_vgpu_total(vgpu_stats) + + self.assertEqual(11, vgpu_total) diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py index 198b6ecbe3..d0eaa445c9 100644 --- a/nova/virt/xenapi/driver.py +++ b/nova/virt/xenapi/driver.py @@ -404,6 +404,16 @@ class XenAPIDriver(driver.ComputeDriver): 'username': CONF.xenserver.connection_username, 'password': CONF.xenserver.connection_password} + def _get_vgpu_total(self, vgpu_stats): + # NOTE(jianghuaw): Now we only enable one vGPU type in one + # compute node. So normally vgpu_stats should contain only + # one GPU group. If there are multiple GPU groups, they + # must contain the same vGPU type. So just add them up. + total = 0 + for grp_id in vgpu_stats: + total += vgpu_stats[grp_id]['total'] + return total + def get_inventory(self, nodename): """Return a dict, keyed by resource class, of inventory information for the supplied node. @@ -413,6 +423,7 @@ class XenAPIDriver(driver.ComputeDriver): vcpus = host_stats['host_cpu_info']['cpu_count'] memory_mb = int(host_stats['host_memory_total'] / units.Mi) disk_gb = int(host_stats['disk_total'] / units.Gi) + vgpus = self._get_vgpu_total(host_stats['vgpu_stats']) result = { fields.ResourceClass.VCPU: { @@ -434,6 +445,20 @@ class XenAPIDriver(driver.ComputeDriver): 'step_size': 1, }, } + if vgpus > 0: + # Only create inventory for vGPU when driver can supply vGPUs. + # At the moment, XenAPI can support up to one vGPU per VM, + # so max_unit is 1. + result.update( + { + fields.ResourceClass.VGPU: { + 'total': vgpus, + 'min_unit': 1, + 'max_unit': 1, + 'step_size': 1, + } + } + ) return result def get_available_resource(self, nodename): |