Merge "Ensure emulator threads are always calculated"

This commit is contained in:
Zuul
2018-03-19 20:49:47 +00:00
committed by Gerrit Code Review
2 changed files with 45 additions and 4 deletions

View File

@@ -3170,3 +3170,29 @@ class EmulatorThreadsTestCase(test.NoDBTestCase):
host_topo, [inst_topo1, inst_topo2])
self.assertEqual(2, host_topo.cells[0].cpu_usage)
self.assertEqual(set([0, 1]), host_topo.cells[0].pinned_cpus)
def test_asymmetric_host(self):
"""Validate behavior with an asymmetric host topology.
The host has three cores, two of which are siblings, and the guest
requires all three of these - two for vCPUs and one for emulator
threads. Ensure that the sibling-ness of the cores is ignored if
necessary.
"""
host_topo = objects.NUMATopology(
cells=[objects.NUMACell(id=0, cpuset=set([1, 2, 3]), memory=2048,
cpu_usage=0,
memory_usage=0,
siblings=[set([1]), set([2, 3])],
mempages=[], pinned_cpus=set([]))])
inst_topo = objects.InstanceNUMATopology(
emulator_threads_policy=(
fields.CPUEmulatorThreadsPolicy.ISOLATE),
cells=[objects.InstanceNUMACell(
id=0,
cpuset=set([0, 1]), memory=2048,
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
self.assertEqual({0: 1, 1: 2}, inst_topo.cells[0].cpu_pinning)
self.assertEqual(set([3]), inst_topo.cells[0].cpuset_reserved)

View File

@@ -675,11 +675,13 @@ def _pack_instance_onto_cores(available_siblings,
' available_siblings: %(siblings)s'
' instance_cell: %(cells)s'
' host_cell_id: %(host_cell_id)s'
' threads_per_core: %(threads_per_core)s',
' threads_per_core: %(threads_per_core)s'
' num_cpu_reserved: %(num_cpu_reserved)s',
{'siblings': available_siblings,
'cells': instance_cell,
'host_cell_id': host_cell_id,
'threads_per_core': threads_per_core})
'threads_per_core': threads_per_core,
'num_cpu_reserved': num_cpu_reserved})
# We build up a data structure that answers the question: 'Given the
# number of threads I want to pack, give me a list of all the available
@@ -866,8 +868,21 @@ def _pack_instance_onto_cores(available_siblings,
if (instance_cell.cpu_thread_policy !=
fields.CPUThreadAllocationPolicy.REQUIRE and
not pinning):
pinning = list(zip(sorted(instance_cell.cpuset),
itertools.chain(*sibling_set)))
threads_no = 1
# we create a fake sibling set by splitting all sibling sets and
# treating each core as if it has no siblings. This is necessary
# because '_get_pinning' will normally only take the same amount of
# cores ('threads_no' cores) from each sibling set. This is rather
# desirable when we're seeking to apply a thread policy but it is
# less desirable when we only care about resource usage as we do
# here. By treating each core as independent, as we do here, we
# maximize resource usage for almost-full nodes at the expense of a
# possible performance impact to the guest.
sibling_set = [set([x]) for x in itertools.chain(*sibling_sets[1])]
pinning, cpuset_reserved = _get_pinning(
threads_no, sibling_set,
instance_cell.cpuset,
num_cpu_reserved=num_cpu_reserved)
threads_no = _threads(instance_cell, threads_no)