Skip to content

Commit fa2ba3a

Browse files
committed
Handle zero pinned CPU in a cell with mixed policy
When cpu_policy is mixed the scheduler tries to find a valid CPU pinning for each instance NUMA cell. However if there is an instance NUMA cell that does not request any pinned CPUs then such logic will calculate empty pinning information for that cell. Then the scheduler logic wrongly assumes that an empty pinning result means there was no valid pinning. However there is difference between a None result when no valid pinning found, from an empty result [] which means there was nothing to pin. This patch makes sure that pinning == None is differentiated from pinning == []. Closes-Bug: #1994526 Change-Id: I5a35a45abfcfbbb858a94927853777f112e73e5b (cherry picked from commit cffe397)
1 parent 2cf835b commit fa2ba3a

File tree

2 files changed

+25
-27
lines changed

2 files changed

+25
-27
lines changed

nova/tests/functional/libvirt/test_numa_servers.py

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -391,34 +391,30 @@ def test_create_server_with_mixed_policy_asymmetric_multi_numa(self):
391391
}
392392
flavor_id = self._create_flavor(
393393
vcpu=3, memory_mb=1024, extra_spec=extra_spec)
394+
expected_usage = {
395+
'DISK_GB': 20, 'MEMORY_MB': 1024, 'PCPU': 2, 'VCPU': 1,
396+
}
394397
# The only possible solution (ignoring the order of vCPU1,2):
395398
# vCPU 0 => pCPU 0, NUMA0, shared
396399
# vCPU 1 => pCPU 6, NUMA1, dedicated
397400
# vCPU 2 => pCPU 7, NUMA1, dedicated
398-
# This is bug 1994526 as the scheduling fails
399-
self._run_build_test(flavor_id, end_status='ERROR')
401+
server = self._run_build_test(
402+
flavor_id, expected_usage=expected_usage)
400403

401-
# # After bug 1994526 is fixed, this should pass
402-
# expected_usage = {
403-
# 'DISK_GB': 20, 'MEMORY_MB': 1024, 'PCPU': 2, 'VCPU': 1,
404-
# }
405-
# server = self._run_build_test(
406-
# flavor_id, expected_usage=expected_usage)
407-
#
408-
# # sanity check the instance topology
409-
# inst = objects.Instance.get_by_uuid(self.ctxt, server['id'])
410-
# self.assertEqual(2, len(inst.numa_topology.cells))
411-
#
412-
# self.assertEqual({0}, inst.numa_topology.cells[0].cpuset)
413-
# self.assertEqual(set(), inst.numa_topology.cells[0].pcpuset)
414-
# self.assertEqual(None, inst.numa_topology.cells[0].cpu_pinning)
415-
#
416-
# self.assertEqual(set(), inst.numa_topology.cells[1].cpuset)
417-
# self.assertEqual({1, 2}, inst.numa_topology.cells[1].pcpuset)
418-
# self.assertEqual(
419-
# {6, 7},
420-
# set(inst.numa_topology.cells[1].cpu_pinning.values())
421-
# )
404+
# sanity check the instance topology
405+
inst = objects.Instance.get_by_uuid(self.ctxt, server['id'])
406+
self.assertEqual(2, len(inst.numa_topology.cells))
407+
408+
self.assertEqual({0}, inst.numa_topology.cells[0].cpuset)
409+
self.assertEqual(set(), inst.numa_topology.cells[0].pcpuset)
410+
self.assertIsNone(inst.numa_topology.cells[0].cpu_pinning)
411+
412+
self.assertEqual(set(), inst.numa_topology.cells[1].cpuset)
413+
self.assertEqual({1, 2}, inst.numa_topology.cells[1].pcpuset)
414+
self.assertEqual(
415+
{6, 7},
416+
set(inst.numa_topology.cells[1].cpu_pinning.values())
417+
)
422418

423419
def test_create_server_with_dedicated_policy_old_configuration(self):
424420
"""Create a server using the legacy extra spec and configuration.

nova/virt/hardware.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ def _get_reserved(sibling_set, vcpus_pinning, num_cpu_reserved=0,
869869
instance_cell.pcpuset)
870870
cpuset_reserved = _get_reserved(
871871
sibling_sets[1], pinning, num_cpu_reserved=num_cpu_reserved)
872-
if not pinning or (num_cpu_reserved and not cpuset_reserved):
872+
if pinning is None or (num_cpu_reserved and not cpuset_reserved):
873873
continue
874874
break
875875

@@ -895,7 +895,7 @@ def _get_reserved(sibling_set, vcpus_pinning, num_cpu_reserved=0,
895895
cpuset_reserved = _get_reserved(
896896
sibling_set, pinning, num_cpu_reserved=num_cpu_reserved)
897897

898-
if not pinning or (num_cpu_reserved and not cpuset_reserved):
898+
if pinning is None or (num_cpu_reserved and not cpuset_reserved):
899899
return
900900
LOG.debug('Selected cores for pinning: %s, in cell %s', pinning,
901901
host_cell.id)
@@ -2607,8 +2607,10 @@ def numa_usage_from_instance_numa(host_topology, instance_topology,
26072607
None, fields.CPUAllocationPolicy.SHARED,
26082608
):
26092609
continue
2610-
2611-
pinned_cpus = set(instance_cell.cpu_pinning.values())
2610+
if instance_cell.cpu_pinning:
2611+
pinned_cpus = set(instance_cell.cpu_pinning.values())
2612+
else:
2613+
pinned_cpus = set()
26122614
if instance_cell.cpuset_reserved:
26132615
pinned_cpus |= instance_cell.cpuset_reserved
26142616

0 commit comments

Comments
 (0)