Skip to content

Commit f77c58d

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Optimize numa_fit_instance_to_host"
2 parents e90fcc1 + 099a6f6 commit f77c58d

File tree

3 files changed

+125
-27
lines changed

3 files changed

+125
-27
lines changed

nova/tests/unit/virt/test_hardware.py

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3836,9 +3836,16 @@ def test_host_numa_fit_instance_to_host_single_cell(self):
38363836
siblings=[set([2]), set([3])])
38373837
])
38383838
inst_topo = objects.InstanceNUMATopology(
3839-
cells=[objects.InstanceNUMACell(
3840-
cpuset=set(), pcpuset=set([0, 1]), memory=2048,
3841-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
3839+
cells=[
3840+
objects.InstanceNUMACell(
3841+
id=0,
3842+
cpuset=set(),
3843+
pcpuset=set([0, 1]),
3844+
memory=2048,
3845+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
3846+
)
3847+
]
3848+
)
38423849

38433850
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
38443851

@@ -3867,9 +3874,16 @@ def test_host_numa_fit_instance_to_host_single_cell_w_usage(self):
38673874
siblings=[set([2]), set([3])])
38683875
])
38693876
inst_topo = objects.InstanceNUMATopology(
3870-
cells=[objects.InstanceNUMACell(
3871-
cpuset=set(), pcpuset=set([0, 1]), memory=2048,
3872-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
3877+
cells=[
3878+
objects.InstanceNUMACell(
3879+
id=0,
3880+
cpuset=set(),
3881+
pcpuset=set([0, 1]),
3882+
memory=2048,
3883+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
3884+
)
3885+
]
3886+
)
38733887

38743888
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
38753889

@@ -3898,9 +3912,16 @@ def test_host_numa_fit_instance_to_host_single_cell_fail(self):
38983912
siblings=[set([2]), set([3])])
38993913
])
39003914
inst_topo = objects.InstanceNUMATopology(
3901-
cells=[objects.InstanceNUMACell(
3902-
cpuset=set(), pcpuset=set([0, 1]), memory=2048,
3903-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
3915+
cells=[
3916+
objects.InstanceNUMACell(
3917+
id=0,
3918+
cpuset=set(),
3919+
pcpuset=set([0, 1]),
3920+
memory=2048,
3921+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
3922+
)
3923+
]
3924+
)
39043925

39053926
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
39063927
self.assertIsNone(inst_topo)
@@ -3927,12 +3948,24 @@ def test_host_numa_fit_instance_to_host_fit(self):
39273948
siblings=[set([4]), set([5]), set([6]), set([7])])
39283949
])
39293950
inst_topo = objects.InstanceNUMATopology(
3930-
cells=[objects.InstanceNUMACell(
3931-
cpuset=set(), pcpuset=set([0, 1]), memory=2048,
3932-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED),
3933-
objects.InstanceNUMACell(
3934-
cpuset=set(), pcpuset=set([2, 3]), memory=2048,
3935-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
3951+
cells=[
3952+
objects.InstanceNUMACell(
3953+
id=0,
3954+
cpuset=set(),
3955+
pcpuset=set([0, 1]),
3956+
memory=2048,
3957+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
3958+
),
3959+
objects.InstanceNUMACell(
3960+
id=1,
3961+
cpuset=set(),
3962+
pcpuset=set([2, 3]),
3963+
memory=2048,
3964+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
3965+
),
3966+
]
3967+
)
3968+
39363969
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
39373970

39383971
for cell in inst_topo.cells:
@@ -3970,12 +4003,24 @@ def test_host_numa_fit_instance_to_host_barely_fit(self):
39704003
])
39714004

39724005
inst_topo = objects.InstanceNUMATopology(
3973-
cells=[objects.InstanceNUMACell(
3974-
cpuset=set(), pcpuset=set([0, 1]), memory=2048,
3975-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED),
3976-
objects.InstanceNUMACell(
3977-
cpuset=set(), pcpuset=set([2, 3]), memory=2048,
3978-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
4006+
cells=[
4007+
objects.InstanceNUMACell(
4008+
id=0,
4009+
cpuset=set(),
4010+
pcpuset=set([0, 1]),
4011+
memory=2048,
4012+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
4013+
),
4014+
objects.InstanceNUMACell(
4015+
id=1,
4016+
cpuset=set(),
4017+
pcpuset=set([2, 3]),
4018+
memory=2048,
4019+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
4020+
),
4021+
]
4022+
)
4023+
39794024
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
39804025

39814026
for cell in inst_topo.cells:
@@ -4003,12 +4048,24 @@ def test_host_numa_fit_instance_to_host_fail_capacity(self):
40034048
siblings=[set([4]), set([5]), set([6]), set([7])])
40044049
])
40054050
inst_topo = objects.InstanceNUMATopology(
4006-
cells=[objects.InstanceNUMACell(
4007-
cpuset=set(), pcpuset=set([0, 1]), memory=2048,
4008-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED),
4009-
objects.InstanceNUMACell(
4010-
cpuset=set(), pcpuset=set([2, 3]), memory=2048,
4011-
cpu_policy=fields.CPUAllocationPolicy.DEDICATED)])
4051+
cells=[
4052+
objects.InstanceNUMACell(
4053+
id=0,
4054+
cpuset=set(),
4055+
pcpuset=set([0, 1]),
4056+
memory=2048,
4057+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
4058+
),
4059+
objects.InstanceNUMACell(
4060+
id=1,
4061+
cpuset=set(),
4062+
pcpuset=set([2, 3]),
4063+
memory=2048,
4064+
cpu_policy=fields.CPUAllocationPolicy.DEDICATED,
4065+
),
4066+
]
4067+
)
4068+
40124069
inst_topo = hw.numa_fit_instance_to_host(host_topo, inst_topo)
40134070
self.assertIsNone(inst_topo)
40144071

nova/virt/hardware.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,12 +2357,37 @@ def numa_fit_instance_to_host(
23572357
host_cells,
23582358
key=lambda cell: total_pci_in_cell.get(cell.id, 0))
23592359

2360+
# a set of host_cell.id, instance_cell.id pairs where we already checked
2361+
# that the instance cell does not fit
2362+
not_fit_cache = set()
2363+
# a set of host_cell.id, instance_cell.id pairs where we already checked
2364+
# that the instance cell does fit
2365+
fit_cache = set()
23602366
for host_cell_perm in itertools.permutations(
23612367
host_cells, len(instance_topology)):
23622368
chosen_instance_cells: ty.List['objects.InstanceNUMACell'] = []
23632369
chosen_host_cells: ty.List['objects.NUMACell'] = []
23642370
for host_cell, instance_cell in zip(
23652371
host_cell_perm, instance_topology.cells):
2372+
2373+
cell_pair = (host_cell.id, instance_cell.id)
2374+
2375+
# if we already checked this pair, and they did not fit then no
2376+
# need to check again just move to the next permutation
2377+
if cell_pair in not_fit_cache:
2378+
break
2379+
2380+
# if we already checked this pair, and they fit before that they
2381+
# will fit now too. So no need to check again. Just continue with
2382+
# the next cell pair in the permutation
2383+
if cell_pair in fit_cache:
2384+
chosen_host_cells.append(host_cell)
2385+
# Normally this would have done by _numa_fit_instance_cell
2386+
# but we optimized that out here based on the cache
2387+
instance_cell.id = host_cell.id
2388+
chosen_instance_cells.append(instance_cell)
2389+
continue
2390+
23662391
try:
23672392
cpuset_reserved = 0
23682393
if (instance_topology.emulator_threads_isolated and
@@ -2379,11 +2404,18 @@ def numa_fit_instance_to_host(
23792404
# This exception will been raised if instance cell's
23802405
# custom pagesize is not supported with host cell in
23812406
# _numa_cell_supports_pagesize_request function.
2407+
2408+
# cache the result
2409+
not_fit_cache.add(cell_pair)
23822410
break
23832411
if got_cell is None:
2412+
# cache the result
2413+
not_fit_cache.add(cell_pair)
23842414
break
23852415
chosen_host_cells.append(host_cell)
23862416
chosen_instance_cells.append(got_cell)
2417+
# cache the result
2418+
fit_cache.add(cell_pair)
23872419

23882420
if len(chosen_instance_cells) != len(host_cell_perm):
23892421
continue
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
fixes:
3+
- |
4+
The algorithm that is used to see if a multi NUMA guest fits to
5+
a multi NUMA host has been optimized to speed up the decision
6+
on hosts with high number of NUMA nodes ( > 8). For details see
7+
`bug 1978372`_
8+
9+
.. _bug 1978372: https://bugs.launchpad.net/nova/+bug/1978372

0 commit comments

Comments
 (0)