Merge "libvirt: Start reporting 'HW_CPU_HYPERTHREADING' trait"
This commit is contained in:
commit
337a35cef8
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user