hardware: fix memory check usage for small/large pages
When huge pages are requested, we need to examine the host cell's
specific huge page amounts, not the amount of physical memory
associated with the host NUMA node.
Also when no pagesize is requested we should consider to compute
memory usage based on small pages since the amount of physical memory
available may also include some large pages.
The unit-tests has been updated to pass correct NUMACell mempages
information since the check is not done based on the pages available
on host. Also that the test 'test_host_usage_contiguous' to reflect to
correct update of pages availalbes on hist based on instance usage.
Closes-bug: #1734204
Change-Id: I5f5c621f2f0fa1bc18ee9a97d17085107a5dee53
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@redhat.com>
(cherry picked from commit 8241deee19
)
This commit is contained in:
parent
43f6f7479c
commit
5e69018038
@ -158,19 +158,19 @@ _NUMA_LIMIT_TOPOLOGIES = {
|
||||
}
|
||||
|
||||
_NUMA_PAGE_TOPOLOGIES = {
|
||||
'2kb*8': objects.NUMAPagesTopology(size_kb=2, total=8, used=0)
|
||||
'2mb*1024': objects.NUMAPagesTopology(size_kb=2048, total=1024, used=0)
|
||||
}
|
||||
|
||||
_NUMA_HOST_TOPOLOGIES = {
|
||||
'2mb': objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([1, 2]), memory=_2MB,
|
||||
cpu_usage=0, memory_usage=0,
|
||||
mempages=[_NUMA_PAGE_TOPOLOGIES['2kb*8']],
|
||||
mempages=[_NUMA_PAGE_TOPOLOGIES['2mb*1024']],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([3, 4]), memory=_2MB,
|
||||
cpu_usage=0, memory_usage=0,
|
||||
mempages=[_NUMA_PAGE_TOPOLOGIES['2kb*8']],
|
||||
mempages=[_NUMA_PAGE_TOPOLOGIES['2mb*1024']],
|
||||
siblings=[set([3]), set([4])],
|
||||
pinned_cpus=set([]))]),
|
||||
}
|
||||
|
@ -1285,66 +1285,82 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
topology.cells[i].cpu_pinning)
|
||||
|
||||
def test_host_usage_contiguous(self):
|
||||
hpages0_4K = objects.NUMAPagesTopology(size_kb=4, total=256, used=0)
|
||||
hpages0_2M = objects.NUMAPagesTopology(size_kb=2048, total=0, used=1)
|
||||
hpages1_4K = objects.NUMAPagesTopology(size_kb=4, total=128, used=2)
|
||||
hpages1_2M = objects.NUMAPagesTopology(size_kb=2048, total=0, used=3)
|
||||
|
||||
hosttopo = objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]), memory=1024,
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]), memory=256,
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
hpages0_4K, hpages0_2M],
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=32768, used=0),
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=2048, total=64, used=32)],
|
||||
siblings=[set([0]), set([1]), set([2]), set([3])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([4, 6]), memory=512,
|
||||
objects.NUMACell(id=1, cpuset=set([4, 6]), memory=256,
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
hpages1_4K, hpages1_2M],
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=32768, used=64),
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=2048, total=64, used=62)],
|
||||
siblings=[set([4]), set([6])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=2, cpuset=set([5, 7]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
objects.NUMACell(id=2, cpuset=set([5, 7]), memory=2,
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=16)],
|
||||
siblings=[set([5]), set([7])],
|
||||
pinned_cpus=set([])),
|
||||
])
|
||||
instance1 = objects.InstanceNUMATopology(cells=[
|
||||
objects.InstanceNUMACell(id=0, cpuset=set([0, 1, 2]), memory=256),
|
||||
objects.InstanceNUMACell(id=1, cpuset=set([4]), memory=256),
|
||||
objects.InstanceNUMACell(id=0, cpuset=set([0, 1, 2]), memory=32),
|
||||
objects.InstanceNUMACell(id=1, cpuset=set([4]), memory=16),
|
||||
])
|
||||
instance2 = objects.InstanceNUMATopology(cells=[
|
||||
objects.InstanceNUMACell(id=0, cpuset=set([0, 1]), memory=256),
|
||||
objects.InstanceNUMACell(id=1, cpuset=set([5, 7]), memory=256),
|
||||
objects.InstanceNUMACell(id=0, cpuset=set([0, 1]), memory=64),
|
||||
objects.InstanceNUMACell(id=1, cpuset=set([2, 3]), memory=32),
|
||||
])
|
||||
instance3 = objects.InstanceNUMATopology(cells=[
|
||||
objects.InstanceNUMACell(id=0, cpuset=set([0, 1]), memory=4,
|
||||
pagesize=2048),
|
||||
objects.InstanceNUMACell(id=1, cpuset=set([2, 3]), memory=4,
|
||||
pagesize=2048),
|
||||
])
|
||||
|
||||
hostusage = hw.numa_usage_from_instances(
|
||||
hosttopo, [instance1, instance2])
|
||||
hosttopo, [instance1, instance2, instance3])
|
||||
|
||||
self.assertEqual(len(hosttopo), len(hostusage))
|
||||
|
||||
# Host NUMA node 0
|
||||
self.assertIsInstance(hostusage.cells[0], objects.NUMACell)
|
||||
self.assertEqual(hosttopo.cells[0].cpuset,
|
||||
hostusage.cells[0].cpuset)
|
||||
self.assertEqual(hosttopo.cells[0].memory,
|
||||
hostusage.cells[0].memory)
|
||||
self.assertEqual(hostusage.cells[0].cpu_usage, 5)
|
||||
self.assertEqual(hostusage.cells[0].memory_usage, 512)
|
||||
self.assertEqual(hostusage.cells[0].mempages, [
|
||||
hpages0_4K, hpages0_2M])
|
||||
self.assertEqual(hostusage.cells[0].cpu_usage, 7)
|
||||
self.assertEqual(hostusage.cells[0].memory_usage, 100)
|
||||
# instance1, instance2 consume 96MiB of small pages
|
||||
self.assertEqual(4, hostusage.cells[0].mempages[0].size_kb)
|
||||
self.assertEqual(24576, hostusage.cells[0].mempages[0].used)
|
||||
# instance3 consumes 4MiB of large pages
|
||||
self.assertEqual(2048, hostusage.cells[0].mempages[1].size_kb)
|
||||
self.assertEqual(34, hostusage.cells[0].mempages[1].used)
|
||||
|
||||
# Host NUMA node 1
|
||||
self.assertIsInstance(hostusage.cells[1], objects.NUMACell)
|
||||
self.assertEqual(hosttopo.cells[1].cpuset,
|
||||
hostusage.cells[1].cpuset)
|
||||
self.assertEqual(hosttopo.cells[1].memory,
|
||||
hostusage.cells[1].memory)
|
||||
self.assertEqual(hostusage.cells[1].cpu_usage, 3)
|
||||
self.assertEqual(hostusage.cells[1].memory_usage, 512)
|
||||
self.assertEqual(hostusage.cells[1].mempages, [
|
||||
hpages1_4K, hpages1_2M])
|
||||
|
||||
self.assertEqual(256, hpages0_4K.total)
|
||||
self.assertEqual(0, hpages0_4K.used)
|
||||
self.assertEqual(0, hpages0_2M.total)
|
||||
self.assertEqual(1, hpages0_2M.used)
|
||||
self.assertEqual(hostusage.cells[1].cpu_usage, 5)
|
||||
self.assertEqual(hostusage.cells[1].memory_usage, 52)
|
||||
# instance1, instance2 consume 48MiB of small pages and 64
|
||||
# pages already used
|
||||
self.assertEqual(4, hostusage.cells[1].mempages[0].size_kb)
|
||||
self.assertEqual(12352, hostusage.cells[1].mempages[0].used)
|
||||
# instance3 consumes 4MiB of large pages
|
||||
self.assertEqual(2048, hostusage.cells[1].mempages[1].size_kb)
|
||||
self.assertEqual(64, hostusage.cells[1].mempages[1].used)
|
||||
|
||||
# Host NUMA node 2
|
||||
self.assertIsInstance(hostusage.cells[2], objects.NUMACell)
|
||||
self.assertEqual(hosttopo.cells[2].cpuset,
|
||||
hostusage.cells[2].cpuset)
|
||||
@ -1352,10 +1368,8 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
hostusage.cells[2].memory)
|
||||
self.assertEqual(hostusage.cells[2].cpu_usage, 0)
|
||||
self.assertEqual(hostusage.cells[2].memory_usage, 0)
|
||||
self.assertEqual(128, hpages1_4K.total)
|
||||
self.assertEqual(2, hpages1_4K.used)
|
||||
self.assertEqual(0, hpages1_2M.total)
|
||||
self.assertEqual(3, hpages1_2M.used)
|
||||
self.assertEqual(4, hostusage.cells[2].mempages[0].size_kb)
|
||||
self.assertEqual(16, hostusage.cells[2].mempages[0].used)
|
||||
|
||||
def test_host_usage_contiguous_pages_compute(self):
|
||||
hosttopo = objects.NUMATopology(cells=[
|
||||
@ -1395,15 +1409,21 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
def test_host_usage_sparse(self):
|
||||
hosttopo = objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]), memory=1024,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2]), set([3])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=5, cpuset=set([4, 6]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([4]), set([6])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=6, cpuset=set([5, 7]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([5]), set([7])],
|
||||
pinned_cpus=set([])),
|
||||
])
|
||||
@ -1413,9 +1433,13 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
])
|
||||
instance2 = objects.InstanceNUMATopology(cells=[
|
||||
objects.InstanceNUMACell(id=0, cpuset=set([0, 1]), memory=256,
|
||||
cpu_usage=0, memory_usage=0, mempages=[]),
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)]),
|
||||
objects.InstanceNUMACell(id=5, cpuset=set([5, 7]), memory=256,
|
||||
cpu_usage=0, memory_usage=0, mempages=[]),
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)]),
|
||||
])
|
||||
|
||||
hostusage = hw.numa_usage_from_instances(
|
||||
@ -1454,15 +1478,21 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
def test_host_usage_culmulative_with_free(self):
|
||||
hosttopo = objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]), memory=1024,
|
||||
cpu_usage=2, memory_usage=512, mempages=[],
|
||||
cpu_usage=2, memory_usage=512, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2]), set([3])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([4, 6]), memory=512,
|
||||
cpu_usage=1, memory_usage=512, mempages=[],
|
||||
cpu_usage=1, memory_usage=512, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([4]), set([6])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=2, cpuset=set([5, 7]), memory=256,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([5]), set([7])],
|
||||
pinned_cpus=set([])),
|
||||
])
|
||||
@ -1575,11 +1605,15 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
def test_topo_usage_none(self):
|
||||
hosttopo = objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([0]), set([1])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([2, 3]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([2]), set([3])],
|
||||
pinned_cpus=set([])),
|
||||
])
|
||||
@ -1611,11 +1645,15 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
def test_topo_usage_mixed(self):
|
||||
hosttopo = objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([0]), set([1])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([2, 3]), memory=512,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([2]), set([3])],
|
||||
pinned_cpus=set([])),
|
||||
])
|
||||
@ -1675,11 +1713,15 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
expected = objects.NUMATopology(
|
||||
cells=[
|
||||
objects.NUMACell(id=1, cpuset=set([1, 2]), memory=1024,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=2, cpuset=set([3, 4]), memory=1024,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=512, used=0)],
|
||||
siblings=[set([3]), set([4])],
|
||||
pinned_cpus=set([]))])
|
||||
got = objects.NUMATopology.obj_from_db_obj(expected._to_json())
|
||||
@ -1691,7 +1733,9 @@ class NUMATopologyTest(test.NoDBTestCase):
|
||||
class VirtNUMATopologyCellUsageTestCase(test.NoDBTestCase):
|
||||
def test_fit_instance_cell_success_no_limit(self):
|
||||
host_cell = objects.NUMACell(id=4, cpuset=set([1, 2]), memory=1024,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([]))
|
||||
instance_cell = objects.InstanceNUMACell(
|
||||
@ -1703,7 +1747,9 @@ class VirtNUMATopologyCellUsageTestCase(test.NoDBTestCase):
|
||||
def test_fit_instance_cell_success_w_limit(self):
|
||||
host_cell = objects.NUMACell(id=4, cpuset=set([1, 2]), memory=1024,
|
||||
cpu_usage=2, memory_usage=1024,
|
||||
mempages=[],
|
||||
mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([]))
|
||||
limit_cell = objects.NUMATopologyLimits(
|
||||
@ -1717,7 +1763,9 @@ class VirtNUMATopologyCellUsageTestCase(test.NoDBTestCase):
|
||||
|
||||
def test_fit_instance_cell_self_overcommit(self):
|
||||
host_cell = objects.NUMACell(id=4, cpuset=set([1, 2]), memory=1024,
|
||||
cpu_usage=0, memory_usage=0, mempages=[],
|
||||
cpu_usage=0, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([]))
|
||||
limit_cell = objects.NUMATopologyLimits(
|
||||
@ -1731,7 +1779,9 @@ class VirtNUMATopologyCellUsageTestCase(test.NoDBTestCase):
|
||||
def test_fit_instance_cell_fail_w_limit(self):
|
||||
host_cell = objects.NUMACell(id=4, cpuset=set([1, 2]), memory=1024,
|
||||
cpu_usage=2, memory_usage=1024,
|
||||
mempages=[],
|
||||
mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([]))
|
||||
instance_cell = objects.InstanceNUMACell(
|
||||
@ -1757,12 +1807,14 @@ class VirtNUMAHostTopologyTestCase(test.NoDBTestCase):
|
||||
cells=[
|
||||
objects.NUMACell(id=1, cpuset=set([1, 2]), memory=2048,
|
||||
cpu_usage=2, memory_usage=2048,
|
||||
mempages=[],
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([1]), set([2])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=2, cpuset=set([3, 4]), memory=2048,
|
||||
cpu_usage=2, memory_usage=2048,
|
||||
mempages=[],
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([3]), set([4])],
|
||||
pinned_cpus=set([]))])
|
||||
|
||||
@ -1963,11 +2015,15 @@ class HelperMethodsTestCase(test.NoDBTestCase):
|
||||
super(HelperMethodsTestCase, self).setUp()
|
||||
self.hosttopo = objects.NUMATopology(cells=[
|
||||
objects.NUMACell(id=0, cpuset=set([0, 1]), memory=512,
|
||||
memory_usage=0, cpu_usage=0, mempages=[],
|
||||
memory_usage=0, cpu_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1])],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([2, 3]), memory=512,
|
||||
memory_usage=0, cpu_usage=0, mempages=[],
|
||||
memory_usage=0, cpu_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([2]), set([3])],
|
||||
pinned_cpus=set([])),
|
||||
])
|
||||
@ -2328,7 +2384,9 @@ class _CPUPinningTestCaseBase(object):
|
||||
class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
def test_get_pinning_inst_too_large_cpu(self):
|
||||
host_pin = objects.NUMACell(id=0, cpuset=set([0, 1, 2]),
|
||||
memory=2048, memory_usage=0, mempages=[],
|
||||
memory=2048, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2])],
|
||||
pinned_cpus=set([]))
|
||||
inst_pin = objects.InstanceNUMACell(cpuset=set([0, 1, 2, 3]),
|
||||
@ -2351,7 +2409,9 @@ class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
|
||||
def test_get_pinning_inst_not_avail(self):
|
||||
host_pin = objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]),
|
||||
memory=2048, memory_usage=0, mempages=[],
|
||||
memory=2048, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
pinned_cpus=set([0]))
|
||||
@ -2363,7 +2423,9 @@ class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
|
||||
def test_get_pinning_no_sibling_fits_empty(self):
|
||||
host_pin = objects.NUMACell(id=0, cpuset=set([0, 1, 2]),
|
||||
memory=2048, memory_usage=0, mempages=[],
|
||||
memory=2048, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2])],
|
||||
pinned_cpus=set([]))
|
||||
inst_pin = objects.InstanceNUMACell(cpuset=set([0, 1, 2]), memory=2048)
|
||||
@ -2377,7 +2439,9 @@ class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
|
||||
def test_get_pinning_no_sibling_fits_w_usage(self):
|
||||
host_pin = objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]),
|
||||
memory=2048, memory_usage=0, mempages=[],
|
||||
memory=2048, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
pinned_cpus=set([1]))
|
||||
@ -2390,7 +2454,9 @@ class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
|
||||
def test_get_pinning_instance_siblings_fits(self):
|
||||
host_pin = objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]),
|
||||
memory=2048, memory_usage=0, mempages=[],
|
||||
memory=2048, memory_usage=0, mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
pinned_cpus=set([]))
|
||||
@ -2408,7 +2474,9 @@ class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
host_pin = objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]),
|
||||
memory=2048, memory_usage=0,
|
||||
siblings=[set([0, 1]), set([2, 3])],
|
||||
mempages=[], pinned_cpus=set([]))
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))
|
||||
inst_pin = objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2, 3]), memory=2048)
|
||||
|
||||
@ -2424,7 +2492,9 @@ class CPUPinningCellTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
id=0, cpuset=set([0, 1, 2, 3, 4, 5, 6, 7]),
|
||||
memory=4096, memory_usage=0,
|
||||
siblings=[set([0, 1]), set([2, 3]), set([4, 5]), set([6, 7])],
|
||||
mempages=[], pinned_cpus=set([]))
|
||||
mempages=[
|
||||
objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)], pinned_cpus=set([]))
|
||||
inst_pin = objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2, 3, 4, 5, 6, 7]), memory=2048)
|
||||
|
||||
@ -2884,7 +2954,9 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
memory_usage=0,
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
inst_pin_1 = objects.InstanceNUMATopology(
|
||||
cells=[objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1]), id=0, memory=2048,
|
||||
@ -2905,7 +2977,8 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
host_pin = objects.NUMATopology(
|
||||
cells=[objects.NUMACell(id=0, cpuset=set([0, 1, 2, 3]),
|
||||
memory=4096, cpu_usage=0, memory_usage=0,
|
||||
mempages=[],
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
pinned_cpus=set([0, 1, 3]))])
|
||||
@ -2929,7 +3002,9 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
memory_usage=0,
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
inst_pin_1 = objects.InstanceNUMATopology(
|
||||
cells=[objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1]), memory=2048, id=0,
|
||||
@ -2951,7 +3026,9 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
memory=4096, cpu_usage=0,
|
||||
memory_usage=0,
|
||||
siblings=[set([0, 2]), set([1, 3])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
inst_pin_1 = objects.InstanceNUMATopology(
|
||||
cells=[objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1]), memory=2048, id=0,
|
||||
@ -2971,7 +3048,8 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
memory=4096, cpu_usage=4,
|
||||
memory_usage=0,
|
||||
siblings=[set([0, 2]), set([1, 3])],
|
||||
mempages=[],
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([0, 1, 2, 3]))])
|
||||
inst_pin_1 = objects.InstanceNUMATopology(
|
||||
cells=[objects.InstanceNUMACell(
|
||||
@ -2994,7 +3072,9 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
memory_usage=0,
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
inst_pin = objects.InstanceNUMATopology(
|
||||
cells=[objects.InstanceNUMACell(
|
||||
cpuset=set([0, 1, 2]), memory=2048, id=0,
|
||||
@ -3015,7 +3095,8 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase):
|
||||
memory_usage=0,
|
||||
siblings=[set([0]), set([1]), set([2]),
|
||||
set([3])],
|
||||
mempages=[],
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([0, 1, 2, 3]))])
|
||||
inst_pin = objects.InstanceNUMATopology(
|
||||
cells=[objects.InstanceNUMACell(
|
||||
@ -3037,7 +3118,9 @@ class CPUSReservedCellTestCase(test.NoDBTestCase):
|
||||
host_cell = objects.NUMACell(id=0, cpuset=set([0, 1, 2]),
|
||||
memory=2048, memory_usage=0,
|
||||
siblings=[set([0]), set([1]), set([2])],
|
||||
mempages=[], pinned_cpus=set([]))
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))
|
||||
inst_cell = objects.InstanceNUMACell(cpuset=set([0, 1]), memory=2048)
|
||||
return hw._numa_fit_instance_cell_with_pinning(
|
||||
host_cell, inst_cell, reserved)
|
||||
@ -3098,11 +3181,15 @@ class EmulatorThreadsTestCase(test.NoDBTestCase):
|
||||
cells=[objects.NUMACell(id=0, cpuset=set([0, 1]), memory=2048,
|
||||
cpu_usage=0, memory_usage=0,
|
||||
siblings=[set([0]), set([1])],
|
||||
mempages=[], pinned_cpus=set([])),
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([])),
|
||||
objects.NUMACell(id=1, cpuset=set([2, 3]), memory=2048,
|
||||
cpu_usage=0, memory_usage=0,
|
||||
siblings=[set([2]), set([3])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
|
||||
def test_single_node_not_defined(self):
|
||||
host_topo = self._host_topology()
|
||||
@ -3269,7 +3356,9 @@ class EmulatorThreadsTestCase(test.NoDBTestCase):
|
||||
memory_usage=0,
|
||||
siblings=[set([0, 1]), set([2, 3]),
|
||||
set([4, 5])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
inst_topo = objects.InstanceNUMATopology(
|
||||
emulator_threads_policy=(
|
||||
fields.CPUEmulatorThreadsPolicy.ISOLATE),
|
||||
@ -3291,7 +3380,9 @@ class EmulatorThreadsTestCase(test.NoDBTestCase):
|
||||
memory_usage=0,
|
||||
siblings=[set([0, 1]), set([2, 3]),
|
||||
set([4, 5])],
|
||||
mempages=[], pinned_cpus=set([0]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([0]))])
|
||||
inst_topo = objects.InstanceNUMATopology(
|
||||
emulator_threads_policy=(
|
||||
fields.CPUEmulatorThreadsPolicy.ISOLATE),
|
||||
@ -3320,7 +3411,9 @@ class EmulatorThreadsTestCase(test.NoDBTestCase):
|
||||
cpu_usage=0,
|
||||
memory_usage=0,
|
||||
siblings=[set([1]), set([2, 3])],
|
||||
mempages=[], pinned_cpus=set([]))])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set([]))])
|
||||
inst_topo = objects.InstanceNUMATopology(
|
||||
emulator_threads_policy=(
|
||||
fields.CPUEmulatorThreadsPolicy.ISOLATE),
|
||||
@ -3340,7 +3433,9 @@ class EmulatorThreadsTestCase(test.NoDBTestCase):
|
||||
memory_usage=0,
|
||||
siblings=[set([1]), set([2, 3]),
|
||||
set([4, 5])],
|
||||
mempages=[], pinned_cpus=set())])
|
||||
mempages=[objects.NUMAPagesTopology(
|
||||
size_kb=4, total=524288, used=0)],
|
||||
pinned_cpus=set())])
|
||||
inst_topo = objects.InstanceNUMATopology(
|
||||
emulator_threads_policy=(
|
||||
fields.CPUEmulatorThreadsPolicy.ISOLATE),
|
||||
|
@ -1017,6 +1017,44 @@ def _numa_fit_instance_cell(host_cell, instance_cell, limit_cell=None,
|
||||
"""
|
||||
LOG.debug('Attempting to fit instance cell %(cell)s on host_cell '
|
||||
'%(host_cell)s', {'cell': instance_cell, 'host_cell': host_cell})
|
||||
|
||||
if 'pagesize' in instance_cell and instance_cell.pagesize:
|
||||
# The instance has requested a page size. Verify that the requested
|
||||
# size is valid and that there are available pages of that size on the
|
||||
# host.
|
||||
pagesize = _numa_cell_supports_pagesize_request(
|
||||
host_cell, instance_cell)
|
||||
if not pagesize:
|
||||
LOG.debug('Host does not support requested memory pagesize. '
|
||||
'Requested: %d kB', instance_cell.pagesize)
|
||||
return
|
||||
LOG.debug('Selected memory pagesize: %(selected_mem_pagesize)d kB. '
|
||||
'Requested memory pagesize: %(requested_mem_pagesize)d '
|
||||
'(small = -1, large = -2, any = -3)',
|
||||
{'selected_mem_pagesize': pagesize,
|
||||
'requested_mem_pagesize': instance_cell.pagesize})
|
||||
instance_cell.pagesize = pagesize
|
||||
else:
|
||||
# The instance provides a NUMA topology but does not define any
|
||||
# particular page size for its memory.
|
||||
if host_cell.mempages:
|
||||
# The host supports explicit page sizes. Use the smallest
|
||||
# available page size.
|
||||
pagesize = _get_smallest_pagesize(host_cell)
|
||||
LOG.debug('No specific pagesize requested for instance, '
|
||||
'selectionned pagesize: %d', pagesize)
|
||||
if not host_cell.can_fit_hugepages(
|
||||
pagesize, instance_cell.memory * units.Ki):
|
||||
LOG.debug('Not enough available memory to schedule instance '
|
||||
'with pagesize %(pagesize)d. Required: '
|
||||
'%(required)s, available: %(available)s, total: '
|
||||
'%(total)s.',
|
||||
{'required': instance_cell.memory,
|
||||
'available': host_cell.avail_memory,
|
||||
'total': host_cell.memory,
|
||||
'pagesize': pagesize})
|
||||
return
|
||||
else:
|
||||
# NOTE (ndipanov): do not allow an instance to overcommit against
|
||||
# itself on any NUMA cell
|
||||
if instance_cell.memory > host_cell.memory:
|
||||
@ -1064,22 +1102,7 @@ def _numa_fit_instance_cell(host_cell, instance_cell, limit_cell=None,
|
||||
{'usage': cpu_usage, 'limit': cpu_limit})
|
||||
return
|
||||
|
||||
pagesize = None
|
||||
if instance_cell.pagesize:
|
||||
pagesize = _numa_cell_supports_pagesize_request(
|
||||
host_cell, instance_cell)
|
||||
if not pagesize:
|
||||
LOG.debug('Host does not support requested memory pagesize. '
|
||||
'Requested: %d kB', instance_cell.pagesize)
|
||||
return
|
||||
LOG.debug('Selected memory pagesize: %(selected_mem_pagesize)d kB. '
|
||||
'Requested memory pagesize: %(requested_mem_pagesize)d '
|
||||
'(small = -1, large = -2, any = -3)',
|
||||
{'selected_mem_pagesize': pagesize,
|
||||
'requested_mem_pagesize': instance_cell.pagesize})
|
||||
|
||||
instance_cell.id = host_cell.id
|
||||
instance_cell.pagesize = pagesize
|
||||
return instance_cell
|
||||
|
||||
|
||||
@ -1743,10 +1766,22 @@ def numa_get_reserved_huge_pages():
|
||||
return bucket
|
||||
|
||||
|
||||
def _get_smallest_pagesize(hostcell):
|
||||
"""Returns the smallest available page size based o hostcell"""
|
||||
avail_pagesize = [page.size_kb for page in hostcell.mempages]
|
||||
avail_pagesize.sort()
|
||||
return avail_pagesize[0]
|
||||
|
||||
|
||||
def _numa_pagesize_usage_from_cell(hostcell, instancecell, sign):
|
||||
if 'pagesize' in instancecell and instancecell.pagesize:
|
||||
pagesize = instancecell.pagesize
|
||||
else:
|
||||
pagesize = _get_smallest_pagesize(hostcell)
|
||||
|
||||
topo = []
|
||||
for pages in hostcell.mempages:
|
||||
if pages.size_kb == instancecell.pagesize:
|
||||
if pages.size_kb == pagesize:
|
||||
topo.append(objects.NUMAPagesTopology(
|
||||
size_kb=pages.size_kb,
|
||||
total=pages.total,
|
||||
@ -1811,7 +1846,7 @@ def numa_usage_from_instances(host, instances, free=False):
|
||||
# guest NUMA node 0.
|
||||
cpu_usage += sign * len(instancecell.cpuset_reserved)
|
||||
|
||||
if instancecell.pagesize and instancecell.pagesize > 0:
|
||||
# Compute mempages usage
|
||||
newcell.mempages = _numa_pagesize_usage_from_cell(
|
||||
newcell, instancecell, sign)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user