Merge "Add 'cpu_policy' and 'cpu_thread_policy' fields"

This commit is contained in:
Jenkins
2016-01-11 21:40:43 +00:00
committed by Gerrit Code Review
5 changed files with 86 additions and 6 deletions
+10
View File
@@ -1974,6 +1974,11 @@ class ImageCPUPinningForbidden(Forbidden):
"CPU pinning policy set against the flavor")
class ImageCPUThreadPolicyForbidden(Forbidden):
msg_fmt = _("Image property 'hw_cpu_thread_policy' is not permitted to "
"override CPU thread pinning policy set against the flavor")
class UnsupportedPolicyException(Invalid):
msg_fmt = _("ServerGroup policy is not supported: %(reason)s")
@@ -2015,6 +2020,11 @@ class RealtimeConfigurationInvalid(Invalid):
"cpu pinning policy")
class CPUThreadPolicyConfigurationInvalid(Invalid):
msg_fmt = _("Cannot set cpu thread pinning policy in a non dedicated "
"cpu pinning policy")
class RequestSpecNotFound(NotFound):
msg_fmt = _("RequestSpec not found for instance %(instance_uuid)s")
+22 -3
View File
@@ -13,6 +13,7 @@
# under the License.
from oslo_serialization import jsonutils
from oslo_utils import versionutils
from nova import db
from nova import exception
@@ -28,7 +29,16 @@ class InstanceNUMACell(base.NovaObject,
# Version 1.0: Initial version
# Version 1.1: Add pagesize field
# Version 1.2: Add cpu_pinning_raw and topology fields
VERSION = '1.2'
# Version 1.3: Add cpu_policy and cpu_thread_policy fields
VERSION = '1.3'
def obj_make_compatible(self, primitive, target_version):
super(InstanceNUMACell, self).obj_make_compatible(primitive,
target_version)
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 3):
primitive.pop('cpu_policy', None)
primitive.pop('cpu_thread_policy', None)
fields = {
'id': obj_fields.IntegerField(),
@@ -37,8 +47,11 @@ class InstanceNUMACell(base.NovaObject,
'pagesize': obj_fields.IntegerField(nullable=True),
'cpu_topology': obj_fields.ObjectField('VirtCPUTopology',
nullable=True),
'cpu_pinning_raw': obj_fields.DictOfIntegersField(nullable=True)
}
'cpu_pinning_raw': obj_fields.DictOfIntegersField(nullable=True),
'cpu_policy': obj_fields.CPUAllocationPolicyField(nullable=True),
'cpu_thread_policy': obj_fields.CPUThreadAllocationPolicyField(
nullable=True),
}
cpu_pinning = obj_fields.DictProxyField('cpu_pinning_raw')
@@ -53,6 +66,12 @@ class InstanceNUMACell(base.NovaObject,
if 'cpu_pinning' not in kwargs:
self.cpu_pinning = None
self.obj_reset_changes(['cpu_pinning_raw'])
if 'cpu_policy' not in kwargs:
self.cpu_policy = None
self.obj_reset_changes(['cpu_policy'])
if 'cpu_thread_policy' not in kwargs:
self.cpu_thread_policy = None
self.obj_reset_changes(['cpu_thread_policy'])
def __len__(self):
return len(self.cpuset)
+1 -1
View File
@@ -1148,7 +1148,7 @@ object_data = {
'InstanceList': '2.0-6c8ba6147cca3082b1e4643f795068bf',
'InstanceMapping': '1.0-47ef26034dfcbea78427565d9177fe50',
'InstanceMappingList': '1.0-9e982e3de1613b9ada85e35f69b23d47',
'InstanceNUMACell': '1.2-535ef30e0de2d6a0d26a71bd58ecafc4',
'InstanceNUMACell': '1.3-6991a20992c5faa57fae71a45b40241b',
'InstanceNUMATopology': '1.2-d944a7d6c21e1c773ffdf09c6d025954',
'InstancePCIRequest': '1.1-b1d75ebc716cb12906d9d513890092bf',
'InstancePCIRequests': '1.1-65e38083177726d806684cb1cc0136d2',
+32
View File
@@ -23,6 +23,7 @@ from nova import context
from nova import exception
from nova import objects
from nova.objects import base as base_obj
from nova.objects import fields
from nova.pci import stats
from nova import test
from nova.virt import hardware as hw
@@ -1103,6 +1104,37 @@ class NUMATopologyTest(test.NoDBTestCase):
},
"expect": exception.RealtimeConfigurationInvalid,
},
{
# Invalid CPU thread pinning override
"flavor": objects.Flavor(vcpus=4, memory_mb=2048,
extra_specs={
"hw:numa_nodes": 2, "hw:cpu_policy": "dedicated",
"hw:cpu_thread_policy":
fields.CPUThreadAllocationPolicy.ISOLATE,
}),
"image": {
"properties": {
"hw_cpu_policy": "dedicated",
"hw_cpu_thread_policy":
fields.CPUThreadAllocationPolicy.REQUIRE,
}
},
"expect": exception.ImageCPUThreadPolicyForbidden,
},
{
# Invalid CPU pinning policy with CPU thread pinning
"flavor": objects.Flavor(vcpus=4, memory_mb=2048,
extra_specs={
"hw:cpu_policy": "shared",
"hw:cpu_thread_policy":
fields.CPUThreadAllocationPolicy.ISOLATE,
}),
"image": {
"properties": {}
},
"expect": exception.CPUThreadPolicyConfigurationInvalid,
},
]
for testitem in testdata:
+21 -2
View File
@@ -27,6 +27,7 @@ from nova import context
from nova import exception
from nova.i18n import _
from nova import objects
from nova.objects import fields
from nova.objects import instance as obj_instance
@@ -1018,21 +1019,38 @@ def _add_cpu_pinning_constraint(flavor, image_meta, numa_topology):
if rt and pi != "dedicated":
raise exception.RealtimeConfigurationInvalid()
flavor_thread_policy = flavor.get('extra_specs', {}).get(
'hw:cpu_thread_policy')
image_thread_policy = image_meta.properties.get('hw_cpu_thread_policy')
if not requested:
if flavor_thread_policy or image_thread_policy:
raise exception.CPUThreadPolicyConfigurationInvalid()
return numa_topology
if flavor_thread_policy in [None, fields.CPUThreadAllocationPolicy.PREFER]:
cpu_thread_policy = image_thread_policy
elif image_thread_policy and image_thread_policy != flavor_thread_policy:
raise exception.ImageCPUThreadPolicyForbidden()
else:
cpu_thread_policy = flavor_thread_policy
if numa_topology:
# NOTE(ndipanov) Setting the cpu_pinning attribute to a non-None value
# means CPU pinning was requested
# TODO(sfinucan) Instead of using the "magic" described above, make use
# of the 'InstanceNUMACell.cpu_policy' parameter
for cell in numa_topology.cells:
cell.cpu_pinning = {}
cell.cpu_thread_policy = cpu_thread_policy
return numa_topology
else:
single_cell = objects.InstanceNUMACell(
id=0,
cpuset=set(range(flavor.vcpus)),
memory=flavor.memory_mb,
cpu_pinning={})
cpu_pinning={},
cpu_thread_policy=cpu_thread_policy)
numa_topology = objects.InstanceNUMATopology(cells=[single_cell])
return numa_topology
@@ -1254,7 +1272,8 @@ def instance_topology_from_instance(instance):
cpuset=set(cell['cpuset']),
memory=cell['memory'],
pagesize=cell.get('pagesize'),
cpu_pinning=cell.get('cpu_pinning_raw'))
cpu_pinning=cell.get('cpu_pinning_raw'),
cpu_thread_policy=cell.get('cpu_thread_policy'))
for cell in dict_cells]
instance_numa_topology = objects.InstanceNUMATopology(
cells=cells)