Skip to content

Commit 9fc63c7

Browse files
cbf123stephenfin
authored andcommitted
hardware: Tweak the 'cpu_realtime_mask' handling slightly
If the end-user specifies a cpu_realtime_mask that does not begin with a carat (i.e. it is not a purely-exclusion mask) it's likely that they're expecting us to use the exact mask that they have specified, not realizing that we default to all-vCPUs-are-RT. Let's make nova's behaviour a bit more friendly by correctly handling this scenario. Note that the end-user impact of this is minimal/non-existent. As discussed in bug #1884231, the only way a user could have used this before would be if they'd configured an emulator thread and purposefully set an invalid 'hw:cpu_realtime_mask' set. In fact, they wouldn't have been able to use this value at all if they used API microversion 2.86 (extra spec validation). Part of blueprint use-pcpu-and-vcpu-in-one-instance Change-Id: Id81859186de6fb6b728ad566a532244008fe77d0 Closes-Bug: #1688673
1 parent f5aa144 commit 9fc63c7

File tree

6 files changed

+59
-7
lines changed

6 files changed

+59
-7
lines changed

doc/source/user/flavors.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,9 +625,11 @@ CPU real-time policy
625625
- ``yes``: The guest vCPUs will have a real-time policy
626626

627627
CPU-REALTIME-MASK (coremask):
628-
A coremask indicating which vCPUs **will not** have a real-time policy. This
629-
should start with a ``^``. For example, a value of ``^0-1`` indicates that
630-
all vCPUs *except* vCPUs ``0`` and ``1`` will have a real-time policy.
628+
A coremask indicating which vCPUs **will** or, if starting with a ``^``,
629+
**will not** have a real-time policy. For example, a value of ``0-5``
630+
indicates that vCPUs ``0`` to ``5`` will have a real-time policy.
631+
Conversely, a value of ``^0-1`` indicates that all vCPUs *except* vCPUs
632+
``0`` and ``1`` will have a real-time policy.
631633

632634
.. note::
633635

@@ -641,6 +643,12 @@ CPU real-time policy
641643
to omit this when an emulator thread policy is configured using the
642644
``hw:emulator_threads_policy`` extra spec.
643645

646+
.. versionchanged:: 22.0.0 (Victoria)
647+
648+
Previously, the leading carat was necessary and omitting it would be
649+
equivalent to not setting the mask, resulting in a failure to spawn
650+
the instance.
651+
644652
.. _extra-specs-emulator-threads-policy:
645653

646654
Emulator threads policy

nova/api/validation/extra_specs/hw.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@
3636
),
3737
value={
3838
'type': str,
39-
# NOTE(stephenfin): Yes, these things *have* to start with '^'
40-
'pattern': r'\^\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
39+
'pattern': r'(\^)?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
4140
},
4241
),
4342
]

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def test_spec(self):
5959
def test_value__str(self):
6060
valid_specs = (
6161
# patterns
62+
('hw:cpu_realtime_mask', '0'),
6263
('hw:cpu_realtime_mask', '^0'),
6364
('hw:cpu_realtime_mask', '^0,2-3,1'),
6465
('hw:mem_page_size', 'large'),
@@ -74,7 +75,7 @@ def test_value__str(self):
7475

7576
invalid_specs = (
7677
# patterns
77-
('hw:cpu_realtime_mask', '0'),
78+
('hw:cpu_realtime_mask', 'a'),
7879
('hw:cpu_realtime_mask', '^0,2-3,b'),
7980
('hw:mem_page_size', 'largest'),
8081
('hw:mem_page_size', '2kbits'),

nova/tests/unit/virt/test_hardware.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,42 @@ def test_success_image(self):
38183818
rt = hw.get_realtime_cpu_constraint(flavor, image)
38193819
self.assertEqual(set([2]), rt)
38203820

3821+
def test_success_image_no_exclusion(self):
3822+
flavor = objects.Flavor(
3823+
vcpus=3, memory_mb=2048,
3824+
extra_specs={
3825+
'hw:cpu_realtime': 'true',
3826+
},
3827+
)
3828+
image = objects.ImageMeta.from_dict(
3829+
{"properties": {"hw_cpu_realtime_mask": "1-2"}})
3830+
rt = hw.get_realtime_cpu_constraint(flavor, image)
3831+
self.assertEqual(set([1, 2]), rt)
3832+
3833+
def test_success_image_leading_space(self):
3834+
flavor = objects.Flavor(
3835+
vcpus=3, memory_mb=2048,
3836+
extra_specs={
3837+
'hw:cpu_realtime': 'true',
3838+
},
3839+
)
3840+
image = objects.ImageMeta.from_dict(
3841+
{"properties": {"hw_cpu_realtime_mask": " ^1"}})
3842+
rt = hw.get_realtime_cpu_constraint(flavor, image)
3843+
self.assertEqual(set([0, 2]), rt)
3844+
3845+
def test_success_image_no_implicit_exclusion(self):
3846+
flavor = objects.Flavor(
3847+
vcpus=3, memory_mb=2048,
3848+
extra_specs={
3849+
'hw:cpu_realtime': 'true',
3850+
},
3851+
)
3852+
image = objects.ImageMeta.from_dict(
3853+
{"properties": {"hw_cpu_realtime_mask": "1-2,^1"}})
3854+
rt = hw.get_realtime_cpu_constraint(flavor, image)
3855+
self.assertEqual(set([2]), rt)
3856+
38213857
def test_no_mask_configured(self):
38223858
flavor = objects.Flavor(
38233859
vcpus=3, memory_mb=2048,

nova/virt/hardware.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,10 @@ def get_realtime_cpu_constraint(
17081708

17091709
vcpus_set = set(range(flavor.vcpus))
17101710
if mask:
1711-
vcpus_rt = parse_cpu_spec("0-%d,%s" % (flavor.vcpus - 1, mask))
1711+
if mask.strip().startswith('^'):
1712+
vcpus_rt = parse_cpu_spec("0-%d,%s" % (flavor.vcpus - 1, mask))
1713+
else:
1714+
vcpus_rt = parse_cpu_spec("%s" % (mask))
17121715
else:
17131716
vcpus_rt = set(range(flavor.vcpus))
17141717

releasenotes/notes/bug-1884231-16acf297d88b122e.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ features:
99
It is now possible to allocate all cores in an instance to realtime and
1010
omit the ``hw:cpu_realtime_mask`` extra spec. This requires specifying the
1111
``hw:emulator_threads_policy`` extra spec.
12+
- |
13+
It is now possible to specify a mask in ``hw:cpu_realtime_mask`` without a
14+
leading ``^``. When this is ommitted, the value will specify the cores that
15+
should be included in the set of realtime cores, as opposed to those that
16+
should be excluded.

0 commit comments

Comments
 (0)