summaryrefslogtreecommitdiff
path: root/nova
diff options
context:
space:
mode:
authorJianghua Wang <jianghua.wang@citrix.com>2017-10-30 05:07:31 +0000
committerJianghua Wang <jianghua.wang@citrix.com>2017-11-28 00:30:15 -0800
commit5b83ad63223df5b7ef477d4cdf0fb605dd1bed04 (patch)
treed0e2fc974026a547fd03755ab2623694890daea4 /nova
parent6d2cd197bc312ac4c7b1879f4e64fecc14bb0147 (diff)
downloadnova-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.py48
-rw-r--r--nova/virt/xenapi/driver.py25
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):