Skip to content

Commit c1a4828

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "objects: Introduce the 'CPUAllocationPolicy.MIXED' enum"
2 parents 7c337cd + ba3388d commit c1a4828

File tree

17 files changed

+203
-20
lines changed

17 files changed

+203
-20
lines changed

doc/notification_samples/common_payloads/ImageMetaPropsPayload.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"hw_architecture": "x86_64"
55
},
66
"nova_object.name": "ImageMetaPropsPayload",
7-
"nova_object.version": "1.3"
7+
"nova_object.version": "1.4"
88
}

doc/notification_samples/common_payloads/InstanceNUMACellPayload.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"nova_object.version": "1.1",
2+
"nova_object.version": "1.2",
33
"nova_object.namespace": "nova",
44
"nova_object.name": "InstanceNUMACellPayload",
55
"nova_object.data": {

nova/api/openstack/compute/servers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@
8787
exception.PciRequestAliasNotDefined,
8888
exception.RealtimeConfigurationInvalid,
8989
exception.RealtimeMaskNotFoundOrInvalid,
90+
exception.RequiredMixedInstancePolicy,
91+
exception.RequiredMixedOrRealtimeCPUMask,
9092
)
9193

9294
MIN_COMPUTE_MOVE_BANDWIDTH = 39

nova/api/validation/extra_specs/hw.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,17 @@
6363
'CPUs can run on. If ``shared`` (default), guest CPUs can be '
6464
'overallocated but cannot float across host cores. If '
6565
'``dedicated``, guest CPUs cannot be overallocated but are '
66-
'individually pinned to their own host core.'
66+
'individually pinned to their own host core. ``mixed`` is a '
67+
'policy with which the guest is mixing the overallocated and '
68+
'pinned guest CPUs.'
6769
),
6870
value={
6971
'type': str,
7072
'description': 'The CPU policy.',
7173
'enum': [
7274
'dedicated',
73-
'shared'
75+
'shared',
76+
'mixed',
7477
],
7578
},
7679
),

nova/exception.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,3 +2318,14 @@ class AcceleratorRequestOpFailed(NovaException):
23182318

23192319
class InvalidLibvirtGPUConfig(NovaException):
23202320
msg_fmt = _('Invalid configuration for GPU devices: %(reason)s')
2321+
2322+
2323+
class RequiredMixedInstancePolicy(Invalid):
2324+
msg_fmt = _("Cannot specify 'hw:cpu_dedicated_mask' without the "
2325+
"'mixed' policy.")
2326+
2327+
2328+
class RequiredMixedOrRealtimeCPUMask(Invalid):
2329+
msg_fmt = _("Must specify either 'hw:cpu_dedicated_mask' or "
2330+
"'hw:cpu_realtime_mask' when using 'mixed' CPU policy"
2331+
" instance.")

nova/notifications/objects/image.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ class ImageMetaPropsPayload(base.NotificationPayloadBase):
120120
# Version 1.1: Added 'gop', 'virtio' and 'none' to hw_video_model field
121121
# Version 1.2: Added hw_pci_numa_affinity_policy field
122122
# Version 1.3: Added hw_mem_encryption, hw_pmu and hw_time_hpet fields
123-
VERSION = '1.3'
123+
# Version 1.4: Added 'mixed' to hw_cpu_policy field
124+
VERSION = '1.4'
124125

125126
SCHEMA = {
126127
k: ('image_meta_props', k) for k in image_meta.ImageMetaProps.fields}

nova/notifications/objects/request_spec.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ def __init__(self, numa_topology):
144144
class InstanceNUMACellPayload(base.NotificationPayloadBase):
145145
# Version 1.0: Initial version
146146
# Version 1.1: Added pcpuset field
147-
VERSION = '1.1'
147+
# Version 1.2: Added 'mixed' to cpu_policy field
148+
VERSION = '1.2'
148149

149150
SCHEMA = {
150151
'id': ('numa_cell', 'id'),

nova/objects/fields.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,9 @@ class CPUAllocationPolicy(BaseNovaEnum):
272272

273273
DEDICATED = "dedicated"
274274
SHARED = "shared"
275+
MIXED = "mixed"
275276

276-
ALL = (DEDICATED, SHARED)
277+
ALL = (DEDICATED, SHARED, MIXED)
277278

278279

279280
class CPUThreadAllocationPolicy(BaseNovaEnum):

nova/objects/image_meta.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,22 @@ class ImageMetaProps(base.NovaObject):
175175
# Version 1.23: Added 'hw_pmu' field
176176
# Version 1.24: Added 'hw_mem_encryption' field
177177
# Version 1.25: Added 'hw_pci_numa_affinity_policy' field
178+
# Version 1.26: Added 'mixed' to 'hw_cpu_policy' field
178179
# NOTE(efried): When bumping this version, the version of
179180
# ImageMetaPropsPayload must also be bumped. See its docstring for details.
180-
VERSION = '1.25'
181+
VERSION = '1.26'
181182

182183
def obj_make_compatible(self, primitive, target_version):
183184
super(ImageMetaProps, self).obj_make_compatible(primitive,
184185
target_version)
185186
target_version = versionutils.convert_version_to_tuple(target_version)
187+
if target_version < (1, 26):
188+
policy = primitive.get('hw_cpu_policy', None)
189+
if policy == fields.CPUAllocationPolicy.MIXED:
190+
raise exception.ObjectActionError(
191+
action='obj_make_compatible',
192+
reason='hw_cpu_policy=%s not supported in version %s' %
193+
(policy, target_version))
186194
if target_version < (1, 25):
187195
primitive.pop('hw_pci_numa_affinity_policy', None)
188196
if target_version < (1, 24):

nova/objects/instance_numa.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from nova.db import api as db
2121
from nova import exception
22+
from nova.i18n import _
2223
from nova.objects import base
2324
from nova.objects import fields as obj_fields
2425
from nova.virt import hardware
@@ -34,12 +35,22 @@ class InstanceNUMACell(base.NovaEphemeralObject,
3435
# Version 1.3: Add cpu_policy and cpu_thread_policy fields
3536
# Version 1.4: Add cpuset_reserved field
3637
# Version 1.5: Add pcpuset field
37-
VERSION = '1.5'
38+
# Version 1.6: Add 'mixed' to cpu_policy field
39+
VERSION = '1.6'
3840

3941
def obj_make_compatible(self, primitive, target_version):
4042
super(InstanceNUMACell, self).obj_make_compatible(primitive,
4143
target_version)
4244
target_version = versionutils.convert_version_to_tuple(target_version)
45+
# Instance with a 'mixed' CPU policy could not provide a backward
46+
# compatibility.
47+
if target_version < (1, 6):
48+
if primitive['cpu_policy'] == obj_fields.CPUAllocationPolicy.MIXED:
49+
raise exception.ObjectActionError(
50+
action='obj_make_compatible',
51+
reason=_('mixed instance is not supported in version %s') %
52+
target_version)
53+
4354
# NOTE(huaqiang): Since version 1.5, 'cpuset' is modified to track the
4455
# unpinned CPUs only, with pinned CPUs tracked via 'pcpuset' instead.
4556
# For a backward compatibility, move the 'dedicated' instance CPU list

nova/tests/functional/notification_sample_tests/test_instance.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ def test_rebuild_server(self):
12491249
'nova_object.data': {},
12501250
'nova_object.name': 'ImageMetaPropsPayload',
12511251
'nova_object.namespace': 'nova',
1252-
'nova_object.version': u'1.3'},
1252+
'nova_object.version': u'1.4'},
12531253
'image.size': 58145823,
12541254
'image.tags': [],
12551255
'scheduler_hints': {'_nova_check_type': ['rebuild']},
@@ -1344,7 +1344,7 @@ def test_rebuild_server_with_trusted_cert(self):
13441344
'nova_object.data': {},
13451345
'nova_object.name': 'ImageMetaPropsPayload',
13461346
'nova_object.namespace': 'nova',
1347-
'nova_object.version': u'1.3'},
1347+
'nova_object.version': u'1.4'},
13481348
'image.size': 58145823,
13491349
'image.tags': [],
13501350
'scheduler_hints': {'_nova_check_type': ['rebuild']},

nova/tests/unit/api/validation/extra_specs/test_validators.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def test_value__str(self):
6969
('hw:cpu_thread_policy', 'prefer'),
7070
('hw:emulator_threads_policy', 'isolate'),
7171
('hw:pci_numa_affinity_policy', 'legacy'),
72+
('hw:cpu_policy', 'mixed'),
7273
)
7374
for key, value in valid_specs:
7475
validators.validate(key, value)

nova/tests/unit/compute/test_compute.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13474,10 +13474,17 @@ def test_image_blockdevicemapping_min_disk(self):
1347413474
self.context, image['id'],
1347513475
image, self.instance_type, root_bdm)
1347613476

13477-
def test_cpu_policy(self):
13477+
@mock.patch('nova.virt.hardware.get_dedicated_cpu_constraint')
13478+
def test_cpu_policy(self, dedicated_cpu_mock):
1347813479
image = {'id': uuids.image_id, 'status': 'active'}
1347913480
for v in obj_fields.CPUAllocationPolicy.ALL:
1348013481
image['properties'] = {'hw_cpu_policy': v}
13482+
# 'mixed' policy requires a definition of 'cpu_dedicated_mask'
13483+
if v == obj_fields.CPUAllocationPolicy.MIXED:
13484+
dedicated_cpu_mock.return_value = set([0])
13485+
else:
13486+
dedicated_cpu_mock.return_value = None
13487+
1348113488
self.compute_api._validate_flavor_image(
1348213489
self.context, image['id'], image, self.instance_type, None)
1348313490
image['properties'] = {'hw_cpu_policy': 'bar'}

nova/tests/unit/notifications/objects/test_notification.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ def test_payload_is_not_generated_if_notification_format_is_unversioned(
387387
# ImageMetaProps, so when you see a fail here for that reason, you must
388388
# *also* bump the version of ImageMetaPropsPayload. See its docstring for
389389
# more information.
390-
'ImageMetaPropsPayload': '1.3-9c200c895932163a4e14e6bb385fa1e0',
390+
'ImageMetaPropsPayload': '1.4-036c794843b95a3a39ee70830f5f6557',
391391
'InstanceActionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
392392
'InstanceActionPayload': '1.8-4fa3da9cbf0761f1f700ae578f36dc2f',
393393
'InstanceActionRebuildNotification':
@@ -411,7 +411,7 @@ def test_payload_is_not_generated_if_notification_format_is_unversioned(
411411
'InstanceActionSnapshotPayload': '1.9-c3e0bbaaefafdfa2f8e6e504c2c9b12c',
412412
'InstanceExistsNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
413413
'InstanceExistsPayload': '1.2-e082c02438ee57164829afaeee3bf7f8',
414-
'InstanceNUMACellPayload': '1.1-2a24ab42bf5e8dfa98291402725bf278',
414+
'InstanceNUMACellPayload': '1.2-a367add3378c71c21c817ab2b23db3bf',
415415
'InstanceNUMATopologyPayload': '1.0-247361b152047c18ae9ad1da2544a3c9',
416416
'InstancePCIRequestPayload': '1.0-12d0d61baf183daaafd93cbeeed2956f',
417417
'InstancePCIRequestsPayload': '1.0-6751cffe0c0fabd212aad624f672429a',

nova/tests/unit/objects/test_objects.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ def obj_name(cls):
10771077
'HyperVLiveMigrateData': '1.4-e265780e6acfa631476c8170e8d6fce0',
10781078
'IDEDeviceBus': '1.0-29d4c9f27ac44197f01b6ac1b7e16502',
10791079
'ImageMeta': '1.8-642d1b2eb3e880a367f37d72dd76162d',
1080-
'ImageMetaProps': '1.25-66fc973af215eb5701ed4034bb6f0685',
1080+
'ImageMetaProps': '1.26-b9f136cd10a2b5ffb3ae44332f2f687d',
10811081
'Instance': '2.7-d187aec68cad2e4d8b8a03a68e4739ce',
10821082
'InstanceAction': '1.2-9a5abc87fdd3af46f45731960651efb5',
10831083
'InstanceActionEvent': '1.4-5b1f361bd81989f8bb2c20bb7e8a4cb4',
@@ -1093,7 +1093,7 @@ def obj_name(cls):
10931093
'InstanceList': '2.6-238f125650c25d6d12722340d726f723',
10941094
'InstanceMapping': '1.2-3bd375e65c8eb9c45498d2f87b882e03',
10951095
'InstanceMappingList': '1.3-d34b6ebb076d542ae0f8b440534118da',
1096-
'InstanceNUMACell': '1.5-d6f884326eba8cae60930e06047fc7d9',
1096+
'InstanceNUMACell': '1.6-25d9120d83a18356f4146f2a6fe2cc8d',
10971097
'InstanceNUMATopology': '1.3-ec0030cb0402a49c96da7051c037082a',
10981098
'InstancePCIRequest': '1.3-f6d324f1c337fad4f34892ed5f484c9a',
10991099
'InstancePCIRequests': '1.1-65e38083177726d806684cb1cc0136d2',

nova/tests/unit/virt/test_hardware.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,10 +932,75 @@ def test_cpu_policy_constraint(self):
932932
),
933933
"image": {
934934
"properties": {
935+
"hw_cpu_policy": "shared"
935936
}
936937
},
937938
"expect": fields.CPUAllocationPolicy.DEDICATED
938939
},
940+
{
941+
"flavor": objects.Flavor(
942+
extra_specs={
943+
"hw:cpu_policy": "dedicated"
944+
}
945+
),
946+
"image": {
947+
"properties": {
948+
}
949+
},
950+
"expect": fields.CPUAllocationPolicy.DEDICATED
951+
},
952+
{
953+
954+
"flavor": objects.Flavor(
955+
extra_specs={
956+
"hw:cpu_policy": "mixed"
957+
}
958+
),
959+
"image": {
960+
"properties": {
961+
"hw_cpu_policy": "dedicated"
962+
}
963+
},
964+
"expect": exception.ImageCPUPinningForbidden
965+
},
966+
{
967+
"flavor": objects.Flavor(
968+
extra_specs={
969+
"hw:cpu_policy": "mixed"
970+
}
971+
),
972+
"image": {
973+
"properties": {
974+
"hw_cpu_policy": "mixed"
975+
}
976+
},
977+
"expect": fields.CPUAllocationPolicy.MIXED
978+
},
979+
{
980+
"flavor": objects.Flavor(
981+
extra_specs={
982+
"hw:cpu_policy": "mixed"
983+
}
984+
),
985+
"image": {
986+
"properties": {
987+
"hw_cpu_policy": "shared"
988+
}
989+
},
990+
"expect": fields.CPUAllocationPolicy.MIXED
991+
},
992+
{
993+
"flavor": objects.Flavor(
994+
extra_specs={
995+
"hw:cpu_policy": "mixed"
996+
}
997+
),
998+
"image": {
999+
"properties": {
1000+
}
1001+
},
1002+
"expect": fields.CPUAllocationPolicy.MIXED
1003+
},
9391004
{
9401005
"flavor": objects.Flavor(
9411006
extra_specs={
@@ -949,6 +1014,19 @@ def test_cpu_policy_constraint(self):
9491014
},
9501015
"expect": exception.ImageCPUPinningForbidden
9511016
},
1017+
{
1018+
"flavor": objects.Flavor(
1019+
extra_specs={
1020+
"hw:cpu_policy": "shared"
1021+
}
1022+
),
1023+
"image": {
1024+
"properties": {
1025+
"hw_cpu_policy": "mixed"
1026+
}
1027+
},
1028+
"expect": exception.ImageCPUPinningForbidden
1029+
},
9521030
{
9531031
"flavor": objects.Flavor(
9541032
extra_specs={
@@ -983,6 +1061,15 @@ def test_cpu_policy_constraint(self):
9831061
},
9841062
"expect": fields.CPUAllocationPolicy.DEDICATED
9851063
},
1064+
{
1065+
"flavor": objects.Flavor(),
1066+
"image": {
1067+
"properties": {
1068+
"hw_cpu_policy": "mixed"
1069+
}
1070+
},
1071+
"expect": fields.CPUAllocationPolicy.MIXED
1072+
},
9861073
{
9871074
"flavor": objects.Flavor(),
9881075
"image": {

0 commit comments

Comments
 (0)