Merge "libvirt: Start reporting 'HW_CPU_HYPERTHREADING' trait"

This commit is contained in:
Zuul 2019-09-21 01:41:40 +00:00 committed by Gerrit Code Review
commit 337a35cef8
4 changed files with 88 additions and 4 deletions

View File

@ -22918,11 +22918,21 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_cpu_feature_traits',
new=mock.Mock(return_value={}))
def test_cpu_traits_sev_no_feature_traits(self):
def test_cpu_traits__sev_support(self):
for support in (False, True):
self.drvr._host._supports_amd_sev = support
self.assertEqual({ot.HW_CPU_X86_AMD_SEV: support},
self.drvr._get_cpu_traits())
traits = self.drvr._get_cpu_traits()
self.assertIn(ot.HW_CPU_X86_AMD_SEV, traits)
self.assertEqual(support, traits[ot.HW_CPU_X86_AMD_SEV])
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_cpu_feature_traits',
new=mock.Mock(return_value={}))
def test_cpu_traits__hyperthreading_support(self):
for support in (False, True):
self.drvr._host._has_hyperthreading = support
traits = self.drvr._get_cpu_traits()
self.assertIn(ot.HW_CPU_HYPERTHREADING, traits)
self.assertEqual(support, traits[ot.HW_CPU_HYPERTHREADING])
def test_cpu_traits_with_passthrough_mode(self):
"""Test getting CPU traits when cpu_mmode is 'host-passthrough', traits

View File

@ -1166,6 +1166,56 @@ cg /cgroup/memory cg opt1,opt2 0 0
def test_is_cpu_control_policy_capable_ioerror(self, mock_open):
self.assertFalse(self.host.is_cpu_control_policy_capable())
@mock.patch('nova.virt.libvirt.host.libvirt.Connection.getCapabilities')
def test_has_hyperthreading__true(self, mock_cap):
mock_cap.return_value = """
<capabilities>
<host>
<uuid>1f71d34a-7c89-45cf-95ce-3df20fc6b936</uuid>
<cpu>
</cpu>
<topology>
<cells num='1'>
<cell id='0'>
<cpus num='4'>
<cpu id='0' socket_id='0' core_id='0' siblings='0,2'/>
<cpu id='1' socket_id='0' core_id='1' siblings='1,3'/>
<cpu id='2' socket_id='0' core_id='0' siblings='0,2'/>
<cpu id='3' socket_id='0' core_id='1' siblings='1,3'/>
</cpus>
</cell>
</cells>
</topology>
</host>
</capabilities>
"""
self.assertTrue(self.host.has_hyperthreading)
@mock.patch('nova.virt.libvirt.host.libvirt.Connection.getCapabilities')
def test_has_hyperthreading__false(self, mock_cap):
mock_cap.return_value = """
<capabilities>
<host>
<uuid>1f71d34a-7c89-45cf-95ce-3df20fc6b936</uuid>
<cpu>
</cpu>
<topology>
<cells num='1'>
<cell id='0'>
<cpus num='4'>
<cpu id='0' socket_id='0' core_id='0' siblings='0'/>
<cpu id='1' socket_id='0' core_id='1' siblings='1'/>
<cpu id='2' socket_id='0' core_id='2' siblings='2'/>
<cpu id='3' socket_id='0' core_id='3' siblings='3'/>
</cpus>
</cell>
</cells>
</topology>
</host>
</capabilities>
"""
self.assertFalse(self.host.has_hyperthreading)
vc = fakelibvirt.virConnect

View File

@ -357,8 +357,8 @@ class LibvirtDriver(driver.ComputeDriver):
self._initiator = None
self._fc_wwnns = None
self._fc_wwpns = None
self._caps = None
self._supported_perf_events = []
self.__has_hyperthreading = None
self.firewall_driver = firewall.load_driver(
DEFAULT_FIREWALL_DRIVER,
host=self._host)
@ -10269,6 +10269,8 @@ class LibvirtDriver(driver.ComputeDriver):
"""
traits = self._get_cpu_feature_traits()
traits[ot.HW_CPU_X86_AMD_SEV] = self._host.supports_amd_sev
traits[ot.HW_CPU_HYPERTHREADING] = self._host.has_hyperthreading
return traits
def _get_cpu_feature_traits(self):

View File

@ -119,6 +119,8 @@ class Host(object):
# memoized by the supports_amd_sev property below.
self._supports_amd_sev = None
self._has_hyperthreading = None
@staticmethod
def _get_libvirt_proxy_classes(libvirt_module):
"""Return a tuple for tpool.Proxy's autowrap argument containing all
@ -1188,6 +1190,26 @@ class Host(object):
except IOError:
return False
@property
def has_hyperthreading(self):
"""Determine if host CPU has SMT, a.k.a. HyperThreading.
:return: True if the host has SMT enabled, else False.
"""
if self._has_hyperthreading is not None:
return self._has_hyperthreading
self._has_hyperthreading = False
# we don't use '/capabilities/host/cpu/topology' since libvirt doesn't
# guarantee the accuracy of this information
for cell in self.get_capabilities().host.topology.cells:
if any(len(cpu.siblings) > 1 for cpu in cell.cpus if cpu.siblings):
self._has_hyperthreading = True
break
return self._has_hyperthreading
def _kernel_supports_amd_sev(self):
if not os.path.exists(SEV_KERNEL_PARAM_FILE):
LOG.debug("%s does not exist", SEV_KERNEL_PARAM_FILE)