From 04ebae9dc01ebd24552b5aacd1a0f8b129013a9e Mon Sep 17 00:00:00 2001 From: Artom Lifshitz Date: Fri, 28 Oct 2022 18:09:35 -0400 Subject: Save cell socket correctly when updating host NUMA topology Previously, in numa_usage_from_instance_numa(), any new NUMACell objects we created did not have the `socket` attribute. In some cases this was persisted all the way down to the database. Fix this by copying `socket` from the old_cell. Change-Id: I9ed3c31ccd3220b02d951fc6dbc5ea049a240a68 Closes-Bug: 1995153 --- .../functional/regressions/test_bug_1995153.py | 36 ++++++++++------------ nova/tests/unit/compute/test_compute.py | 2 ++ nova/tests/unit/compute/test_resource_tracker.py | 2 ++ nova/tests/unit/scheduler/fakes.py | 2 ++ nova/tests/unit/virt/test_hardware.py | 29 +++++++++++++++++ nova/virt/hardware.py | 1 + 6 files changed, 53 insertions(+), 19 deletions(-) diff --git a/nova/tests/functional/regressions/test_bug_1995153.py b/nova/tests/functional/regressions/test_bug_1995153.py index c897156d99..f4e61d06df 100644 --- a/nova/tests/functional/regressions/test_bug_1995153.py +++ b/nova/tests/functional/regressions/test_bug_1995153.py @@ -68,16 +68,17 @@ class Bug1995153RegressionTest( side_effect=host_pass_mock)).mock def test_socket_policy_bug_1995153(self): - """The numa_usage_from_instance_numa() method in hardware.py saves the - host NUMAToplogy object with NUMACells that have no `socket` set. This - was an omission in the original implementation of the `socket` PCI NUMA - affinity policy. The consequence is that any code path that calls into - numa_usage_from_instance_numa() will clobber the host NUMA topology in - the database with a socket-less version. Booting an instance with NUMA - toplogy will do that, for example. If then a second instance is booted - with the `socket` PCI NUMA affinity policy, it will read the - socket-less host NUMATopology from the database, and error out with a - NotImplementedError. This is bug 1995153. + """Previously, the numa_usage_from_instance_numa() method in + hardware.py saved the host NUMAToplogy object with NUMACells that have + no `socket` set. This was an omission in the original implementation of + the `socket` PCI NUMA affinity policy. The consequence was that any + code path that called into numa_usage_from_instance_numa() would + clobber the host NUMA topology in the database with a socket-less + version. Booting an instance with NUMA toplogy would do that, for + example. If then a second instance was booted with the `socket` PCI + NUMA affinity policy, it would read the socket-less host NUMATopology + from the database, and error out with a NotImplementedError. This was + bug 1995153. Demonstrate that this is fixed. """ host_info = fakelibvirt.HostInfo( cpu_nodes=2, cpu_sockets=1, cpu_cores=2, cpu_threads=2, @@ -92,18 +93,15 @@ class Bug1995153RegressionTest( 'pci_passthrough:alias': '%s:1' % self.ALIAS_NAME, 'hw:pci_numa_affinity_policy': 'socket' } - # Boot a first instance with a guest NUMA topology to run the buggy - # code in numa_usage_from_instance_numa() and save the socket-less host - # NUMATopology to the database. + # Boot a first instance with a guest NUMA topology to run the + # numa_usage_from_instance_numa() and update the host NUMATopology in + # the database. self._create_server( flavor_id=self._create_flavor( extra_spec={'hw:cpu_policy': 'dedicated'})) - # FIXME(artom) Attempt to boot an instance with the `socket` PCI NUMA - # affinity policy and observe the fireworks. + # Boot an instance with the `socket` PCI NUMA affinity policy and + # assert that it boots correctly now. flavor_id = self._create_flavor(extra_spec=extra_spec) - server = self._create_server(flavor_id=flavor_id, - expected_state='ERROR') - self.assertIn('fault', server) - self.assertIn('NotImplementedError', server['fault']['message']) + self._create_server(flavor_id=flavor_id) self.assertTrue(self.mock_filter.called) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 49cf15ec17..f62468544d 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -5672,6 +5672,7 @@ class ComputeTestCase(BaseTestCase, pagesize=2048, cpu_usage=2, memory_usage=0, + socket=0, pinned_cpus=set([1, 2]), siblings=[set([1]), set([2])], mempages=[objects.NUMAPagesTopology( @@ -5687,6 +5688,7 @@ class ComputeTestCase(BaseTestCase, pagesize=2048, memory_usage=0, cpu_usage=0, + socket=0, siblings=[set([3]), set([4])], mempages=[objects.NUMAPagesTopology( size_kb=2048, total=256, used=0)]) diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py index cd36b8987f..101e96f83f 100644 --- a/nova/tests/unit/compute/test_resource_tracker.py +++ b/nova/tests/unit/compute/test_resource_tracker.py @@ -181,6 +181,7 @@ _NUMA_HOST_TOPOLOGIES = { memory=_2MB, cpu_usage=0, memory_usage=0, + socket=0, mempages=[_NUMA_PAGE_TOPOLOGIES['2mb*1024']], siblings=[set([1]), set([2])], pinned_cpus=set()), @@ -191,6 +192,7 @@ _NUMA_HOST_TOPOLOGIES = { memory=_2MB, cpu_usage=0, memory_usage=0, + socket=0, mempages=[_NUMA_PAGE_TOPOLOGIES['2mb*1024']], siblings=[set([3]), set([4])], pinned_cpus=set())]), diff --git a/nova/tests/unit/scheduler/fakes.py b/nova/tests/unit/scheduler/fakes.py index 658c82c20e..f5dcf87e4a 100644 --- a/nova/tests/unit/scheduler/fakes.py +++ b/nova/tests/unit/scheduler/fakes.py @@ -34,6 +34,7 @@ NUMA_TOPOLOGY = objects.NUMATopology(cells=[ memory=512, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=16, total=387184, used=0), @@ -46,6 +47,7 @@ NUMA_TOPOLOGY = objects.NUMATopology(cells=[ memory=512, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=1548736, used=0), diff --git a/nova/tests/unit/virt/test_hardware.py b/nova/tests/unit/virt/test_hardware.py index 753ee41550..ab51a3e26c 100644 --- a/nova/tests/unit/virt/test_hardware.py +++ b/nova/tests/unit/virt/test_hardware.py @@ -2023,6 +2023,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=256, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=32768, used=0), @@ -2036,6 +2037,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=256, cpu_usage=0, memory_usage=0, + socket=1, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=32768, used=64), @@ -2049,6 +2051,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=2, cpu_usage=0, memory_usage=0, + socket=2, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=16)], @@ -2130,6 +2133,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=160, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=32768, used=32), @@ -2170,6 +2174,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=1024, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=0)], @@ -2181,6 +2186,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=512, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=0)], @@ -2192,6 +2198,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=512, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=0)], @@ -2258,6 +2265,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=1024, cpu_usage=2, memory_usage=512, + socket=0, mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=0)], siblings=[set([0]), set([1]), set([2]), set([3])], @@ -2269,6 +2277,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=512, cpu_usage=1, memory_usage=512, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=0)], @@ -2280,6 +2289,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=256, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[ objects.NUMAPagesTopology(size_kb=4, total=512, used=0)], @@ -2330,6 +2340,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=512, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[objects.NUMAPagesTopology( size_kb=2048, total=512, used=128, @@ -2342,6 +2353,7 @@ class NUMATopologyTest(test.NoDBTestCase): memory=512, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), mempages=[objects.NUMAPagesTopology( size_kb=1048576, total=5, used=2, @@ -2606,6 +2618,7 @@ class VirtNUMAHostTopologyTestCase(test.NoDBTestCase): memory=2048, cpu_usage=2, memory_usage=2048, + socket=0, pinned_cpus=set(), mempages=[objects.NUMAPagesTopology( size_kb=4, total=524288, used=0)], @@ -2616,6 +2629,7 @@ class VirtNUMAHostTopologyTestCase(test.NoDBTestCase): memory=2048, cpu_usage=2, memory_usage=2048, + socket=0, pinned_cpus=set(), mempages=[objects.NUMAPagesTopology( size_kb=4, total=524288, used=0)], @@ -4162,6 +4176,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([0]), set([1]), set([2]), set([3])], mempages=[objects.NUMAPagesTopology( @@ -4191,6 +4206,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set([0, 1, 3]), mempages=[objects.NUMAPagesTopology( size_kb=4, total=524288, used=0)], @@ -4220,6 +4236,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([0]), set([1]), set([2]), set([3])], mempages=[objects.NUMAPagesTopology( @@ -4248,6 +4265,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([0, 2]), set([1, 3])], mempages=[objects.NUMAPagesTopology( @@ -4274,6 +4292,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set([0, 1, 2, 3]), siblings=[set([0, 2]), set([1, 3])], mempages=[objects.NUMAPagesTopology( @@ -4300,6 +4319,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([0]), set([1]), set([2]), set([3])], mempages=[objects.NUMAPagesTopology( @@ -4326,6 +4346,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set([0, 1, 2, 3]), siblings=[set([0]), set([1]), set([2]), set([3])], mempages=[objects.NUMAPagesTopology( @@ -4355,6 +4376,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set([2]), siblings=[set([0, 4]), set([1, 5]), set([2, 6]), set([3, 7])], mempages=[objects.NUMAPagesTopology( @@ -4385,6 +4407,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=2, memory_usage=0, + socket=0, pinned_cpus=set([2, 6, 7]), siblings=[set([0, 4]), set([1, 5]), set([2, 6]), set([3, 7])], mempages=[objects.NUMAPagesTopology( @@ -4417,6 +4440,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): cpu_usage=2, memory_usage=0, pinned_cpus=set(), + socket=0, siblings=[{cpu} for cpu in range(8)], mempages=[objects.NUMAPagesTopology( size_kb=4, total=524288, used=0)] @@ -4450,6 +4474,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=2, memory_usage=0, + socket=0, pinned_cpus=set([0, 1, 2, 3]), siblings=[{cpu} for cpu in range(8)], mempages=[objects.NUMAPagesTopology( @@ -4492,6 +4517,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=2, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([0, 5]), set([1, 6]), set([2, 7]), set([3, 8]), set([4, 9])], @@ -4531,6 +4557,7 @@ class CPUPinningTestCase(test.NoDBTestCase, _CPUPinningTestCaseBase): memory=4096, cpu_usage=2, memory_usage=0, + socket=0, pinned_cpus=set([0, 1, 2, 5, 6, 7]), siblings=[set([0, 5]), set([1, 6]), set([2, 7]), set([3, 8]), set([4, 9])], @@ -4766,6 +4793,7 @@ class EmulatorThreadsTestCase(test.NoDBTestCase): memory=2048, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([0]), set([1])], mempages=[objects.NUMAPagesTopology( @@ -4777,6 +4805,7 @@ class EmulatorThreadsTestCase(test.NoDBTestCase): memory=2048, cpu_usage=0, memory_usage=0, + socket=0, pinned_cpus=set(), siblings=[set([2]), set([3])], mempages=[objects.NUMAPagesTopology( diff --git a/nova/virt/hardware.py b/nova/virt/hardware.py index c8f8bb2481..292536735a 100644 --- a/nova/virt/hardware.py +++ b/nova/virt/hardware.py @@ -2583,6 +2583,7 @@ def numa_usage_from_instance_numa(host_topology, instance_topology, cpuset=host_cell.cpuset, pcpuset=host_cell.pcpuset, memory=host_cell.memory, + socket=host_cell.socket, cpu_usage=0, memory_usage=0, mempages=host_cell.mempages, -- cgit v1.2.1