Skip to content

Commit edaaa97

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Support Cpu Compararion on Aarch64 Platform"
2 parents 39b6892 + a6ef502 commit edaaa97

File tree

4 files changed

+78
-18
lines changed

4 files changed

+78
-18
lines changed

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10978,22 +10978,49 @@ def test_compare_cpu_handles_not_supported_error_gracefully(self,
1097810978
instance)
1097910979
self.assertIsNone(ret)
1098010980

10981-
@mock.patch.object(host.Host, 'compare_cpu')
10981+
@mock.patch.object(fakelibvirt.Connection, 'getLibVersion',
10982+
return_value=versionutils.convert_version_to_int(
10983+
libvirt_driver.MIN_LIBVIRT_AARCH64_CPU_COMPARE) - 1
10984+
)
1098210985
@mock.patch.object(nova.virt.libvirt, 'config')
1098310986
def test_compare_cpu_aarch64_skip_comparison(self,
1098410987
mock_vconfig,
10985-
mock_compare):
10988+
mock_get_libversion):
1098610989
instance = objects.Instance(**self.test_instance)
10987-
skip_comparison_exc = fakelibvirt.make_libvirtError(
10988-
fakelibvirt.libvirtError,
10989-
'Host CPU compatibility check does not make '
10990-
'sense on AArch64; skip CPU comparison')
10991-
mock_compare.side_effect = skip_comparison_exc
10990+
self.mock_uname.return_value = fakelibvirt.os_uname(
10991+
'Linux', '', '5.4.0-0-generic', '', fields.Architecture.AARCH64)
1099210992
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
1099310993
ret = conn._compare_cpu(None, jsonutils.dumps(_fake_cpu_info_aarch64),
1099410994
instance)
1099510995
self.assertIsNone(ret)
1099610996

10997+
@mock.patch.object(host.Host, 'get_capabilities')
10998+
@mock.patch.object(fakelibvirt.Connection, 'getLibVersion',
10999+
return_value=versionutils.convert_version_to_int(
11000+
libvirt_driver.MIN_LIBVIRT_AARCH64_CPU_COMPARE))
11001+
@mock.patch.object(host.Host, 'compare_cpu')
11002+
def test_compare_cpu_host_aarch64(self,
11003+
mock_compare,
11004+
mock_get_libversion,
11005+
mock_caps):
11006+
instance = objects.Instance(**self.test_instance)
11007+
mock_compare.return_value = 6
11008+
caps = vconfig.LibvirtConfigCaps()
11009+
caps.host = vconfig.LibvirtConfigCapsHost()
11010+
caps.host.cpu = vconfig.LibvirtConfigCPU()
11011+
caps.host.cpu.arch = fields.Architecture.AARCH64
11012+
caps.host.topology = fakelibvirt.NUMATopology()
11013+
11014+
mock_caps.return_value = caps
11015+
self.mock_uname.return_value = fakelibvirt.os_uname(
11016+
'Linux', '', '5.4.0-0-generic', '', fields.Architecture.AARCH64)
11017+
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
11018+
ret = conn._compare_cpu(None,
11019+
jsonutils.dumps(_fake_cpu_info_aarch64),
11020+
instance)
11021+
mock_compare.assert_called_once_with(caps.host.cpu.to_xml())
11022+
self.assertIsNone(ret)
11023+
1099711024
@mock.patch.object(host.Host, 'compare_cpu')
1099811025
@mock.patch.object(nova.virt.libvirt.LibvirtDriver,
1099911026
'_vcpu_model_to_cpu_config')

nova/tests/unit/virt/libvirt/test_host.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,23 @@ def test_get_capabilities_no_host_cpu_model(self):
689689
self.assertIsNone(caps.host.cpu.model)
690690
self.assertEqual(0, len(caps.host.cpu.features))
691691

692+
def test_get_capabilities_on_aarch64(self):
693+
"""Tests that cpu features are not retrieved on aarch64 platform.
694+
"""
695+
fake_caps_xml = '''
696+
<capabilities>
697+
<host>
698+
<uuid>cef19ce0-0ca2-11df-855d-b193fbce7686</uuid>
699+
<cpu>
700+
<arch>aarch64</arch>
701+
</cpu>
702+
</host>
703+
</capabilities>'''
704+
with mock.patch.object(fakelibvirt.virConnect, 'getCapabilities',
705+
return_value=fake_caps_xml):
706+
caps = self.host.get_capabilities()
707+
self.assertEqual(0, len(caps.host.cpu.features))
708+
692709
def test__get_machine_types(self):
693710
expected = [
694711
# NOTE(aspiers): in the real world, i686 would probably

nova/virt/libvirt/driver.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ def repr_method(self):
219219
NEXT_MIN_LIBVIRT_VERSION = (7, 0, 0)
220220
NEXT_MIN_QEMU_VERSION = (5, 2, 0)
221221

222+
MIN_LIBVIRT_AARCH64_CPU_COMPARE = (6, 9, 0)
223+
222224
# Virtuozzo driver support
223225
MIN_VIRTUOZZO_VERSION = (7, 0, 0)
224226

@@ -9394,6 +9396,20 @@ def _compare_cpu(self, guest_cpu, host_cpu_str, instance):
93949396
else:
93959397
cpu = self._vcpu_model_to_cpu_config(guest_cpu)
93969398

9399+
host_cpu = self._host.get_capabilities().host.cpu
9400+
if host_cpu.arch == fields.Architecture.AARCH64:
9401+
if self._host.has_min_version(MIN_LIBVIRT_AARCH64_CPU_COMPARE):
9402+
LOG.debug("On AArch64 hosts, source and destination host "
9403+
"CPUs are compared to check if they're compatible"
9404+
"(the only use-case supported by libvirt for "
9405+
"Arm64/AArch64)")
9406+
cpu = host_cpu
9407+
else:
9408+
LOG.debug("You need %s libvirt version to be able to compare "
9409+
"source host CPU with destination host CPU; skip "
9410+
"CPU comparison", MIN_LIBVIRT_AARCH64_CPU_COMPARE)
9411+
return
9412+
93979413
u = ("http://libvirt.org/html/libvirt-libvirt-host.html#"
93989414
"virCPUCompareResult")
93999415
m = _("CPU doesn't have compatibility.\n\n%(ret)s\n\nRefer to %(u)s")
@@ -9403,10 +9419,6 @@ def _compare_cpu(self, guest_cpu, host_cpu_str, instance):
94039419
LOG.debug("cpu compare xml: %s", cpu_xml, instance=instance)
94049420
ret = self._host.compare_cpu(cpu_xml)
94059421
except libvirt.libvirtError as e:
9406-
if cpu.arch == fields.Architecture.AARCH64:
9407-
LOG.debug("Host CPU compatibility check does not make "
9408-
"sense on AArch64; skip CPU comparison")
9409-
return
94109422
error_code = e.get_error_code()
94119423
if error_code == libvirt.VIR_ERR_NO_SUPPORT:
94129424
LOG.debug("URI %(uri)s does not support cpu comparison. "

nova/virt/libvirt/host.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -793,13 +793,17 @@ def get_capabilities(self):
793793
xml_str = self._caps.host.cpu.to_xml()
794794
if isinstance(xml_str, bytes):
795795
xml_str = xml_str.decode('utf-8')
796-
features = self.get_connection().baselineCPU(
797-
[xml_str],
798-
libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
799-
if features:
800-
cpu = vconfig.LibvirtConfigCPU()
801-
cpu.parse_str(features)
802-
self._caps.host.cpu.features = cpu.features
796+
# NOTE(kevinz): The baseline CPU info on Aarch64 will not
797+
# include any features. So on Aarch64, we use the original
798+
# features from LibvirtConfigCaps.
799+
if self._caps.host.cpu.arch != fields.Architecture.AARCH64:
800+
features = self.get_connection().baselineCPU(
801+
[xml_str],
802+
libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
803+
if features:
804+
cpu = vconfig.LibvirtConfigCPU()
805+
cpu.parse_str(features)
806+
self._caps.host.cpu.features = cpu.features
803807
except libvirt.libvirtError as ex:
804808
error_code = ex.get_error_code()
805809
if error_code == libvirt.VIR_ERR_NO_SUPPORT:

0 commit comments

Comments
 (0)