Support old & new versions of svm and vmx traits
I1c9a72d19ef9dadfb931efa3894867099974bcc7 added new Intel- and AMD-specific trait namespaces for certain X86 CPU features, including a couple that had already been defined in the generic X86 namespace (the Intel-specific 'vmx' feature and the AMD-specific 'svm' feature). Unfortunately, the libvirt driver was already exposing the generic versions of these. For backward compatibility reasons, we have to continue exposing those versions of those traits. But we also need to expose the new arch-namespaced versions. We accomplish this by reworking libvirt's CPU_TRAITS_MAPPING such that the values can be tuples of traits, all of which are set when the feature corresponding to the key is enabled. Change-Id: Ib29c975d3d4e1adf14e215b1a28d30681ee16a77
This commit is contained in:
parent
a4068802ef
commit
b420c343f2
@ -81,7 +81,10 @@ class LibvirtReportTraitsTests(LibvirtReportTraitsTestBase):
|
||||
# trait values are coming from fakelibvirt's baselineCPU result.
|
||||
# COMPUTE_NODE is always set on the compute node provider.
|
||||
traits = self._get_provider_traits(self.host_uuid)
|
||||
for trait in ('HW_CPU_X86_VMX', 'HW_CPU_X86_AESNI', 'COMPUTE_NODE'):
|
||||
for trait in (
|
||||
'HW_CPU_X86_VMX', 'HW_CPU_X86_INTEL_VMX', 'HW_CPU_X86_AESNI',
|
||||
'COMPUTE_NODE',
|
||||
):
|
||||
self.assertIn(trait, traits)
|
||||
|
||||
self._create_trait('CUSTOM_TRAITS')
|
||||
@ -96,10 +99,14 @@ class LibvirtReportTraitsTests(LibvirtReportTraitsTestBase):
|
||||
# and it's not in the baseline for the host.
|
||||
traits = set(self._get_provider_traits(self.host_uuid))
|
||||
expected_traits = self.expected_libvirt_driver_capability_traits.union(
|
||||
[u'HW_CPU_X86_VMX', u'HW_CPU_X86_AESNI', u'CUSTOM_TRAITS',
|
||||
# The periodic restored the COMPUTE_NODE trait.
|
||||
u'COMPUTE_NODE']
|
||||
)
|
||||
[
|
||||
'HW_CPU_X86_VMX',
|
||||
'HW_CPU_X86_INTEL_VMX',
|
||||
'HW_CPU_X86_AESNI',
|
||||
'CUSTOM_TRAITS',
|
||||
# The periodic restored the COMPUTE_NODE trait.
|
||||
'COMPUTE_NODE',
|
||||
])
|
||||
for trait in expected_traits:
|
||||
self.assertIn(trait, traits)
|
||||
|
||||
|
@ -21101,7 +21101,7 @@ class TestUpdateProviderTree(test.NoDBTestCase):
|
||||
pcpus = 12
|
||||
memory_mb = 1024
|
||||
disk_gb = 200
|
||||
cpu_traits = {t: False for t in libvirt_utils.CPU_TRAITS_MAPPING.values()}
|
||||
cpu_traits = libvirt_utils.cpu_features_to_traits({})
|
||||
|
||||
def setUp(self):
|
||||
super(TestUpdateProviderTree, self).setUp()
|
||||
@ -21816,7 +21816,7 @@ class TraitsComparisonMixin(object):
|
||||
|
||||
def assertTraitsEqual(self, expected, actual):
|
||||
exp = {t: t in expected
|
||||
for t in libvirt_utils.CPU_TRAITS_MAPPING.values()}
|
||||
for t in libvirt_utils.cpu_features_to_traits({})}
|
||||
self.assertEqual(exp, actual)
|
||||
|
||||
|
||||
@ -25538,8 +25538,9 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
|
||||
are calculated from fakelibvirt's baseline CPU features.
|
||||
"""
|
||||
self.flags(cpu_mode='host-passthrough', group='libvirt')
|
||||
self.assertTraitsEqual(['HW_CPU_X86_AESNI', 'HW_CPU_X86_VMX'],
|
||||
self.drvr._get_cpu_feature_traits())
|
||||
self.assertTraitsEqual(
|
||||
['HW_CPU_X86_AESNI', 'HW_CPU_X86_VMX', 'HW_CPU_X86_INTEL_VMX'],
|
||||
self.drvr._get_cpu_feature_traits())
|
||||
|
||||
@mock.patch('nova.virt.libvirt.host.libvirt.Connection.baselineCPU')
|
||||
def test_cpu_traits_with_mode_none(self, mock_baseline):
|
||||
@ -25548,9 +25549,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
|
||||
"""
|
||||
self.flags(cpu_mode='none', group='libvirt')
|
||||
mock_baseline.return_value = _fake_qemu64_cpu_feature
|
||||
self.assertTraitsEqual(['HW_CPU_X86_SSE', 'HW_CPU_X86_SVM',
|
||||
'HW_CPU_X86_MMX', 'HW_CPU_X86_SSE2'],
|
||||
self.drvr._get_cpu_feature_traits())
|
||||
self.assertTraitsEqual(
|
||||
['HW_CPU_X86_SSE', 'HW_CPU_X86_SVM', 'HW_CPU_X86_AMD_SVM',
|
||||
'HW_CPU_X86_MMX', 'HW_CPU_X86_SSE2'],
|
||||
self.drvr._get_cpu_feature_traits())
|
||||
|
||||
mock_baseline.assert_called_with([u'''<cpu>
|
||||
<arch>x86_64</arch>
|
||||
@ -25638,6 +25640,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
|
||||
'HW_CPU_X86_SSE2',
|
||||
'HW_CPU_X86_SSE',
|
||||
'HW_CPU_X86_MMX',
|
||||
'HW_CPU_X86_AMD_SVM',
|
||||
'HW_CPU_X86_SVM'
|
||||
], self.drvr._get_cpu_feature_traits()
|
||||
)
|
||||
@ -25705,6 +25708,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
|
||||
'HW_CPU_X86_SSE2',
|
||||
'HW_CPU_X86_SSE',
|
||||
'HW_CPU_X86_MMX',
|
||||
'HW_CPU_X86_AMD_SVM',
|
||||
'HW_CPU_X86_SVM'
|
||||
], self.drvr._get_cpu_feature_traits()
|
||||
)
|
||||
|
@ -93,9 +93,13 @@ CPU_TRAITS_MAPPING = {
|
||||
'sse4.2': os_traits.HW_CPU_X86_SSE42,
|
||||
'sse4a': os_traits.HW_CPU_X86_SSE4A,
|
||||
'ssse3': os_traits.HW_CPU_X86_SSSE3,
|
||||
'svm': os_traits.HW_CPU_X86_SVM,
|
||||
# We have to continue to support the old (generic) trait for the
|
||||
# AMD-specific svm feature.
|
||||
'svm': (os_traits.HW_CPU_X86_SVM, os_traits.HW_CPU_X86_AMD_SVM),
|
||||
'tbm': os_traits.HW_CPU_X86_TBM,
|
||||
'vmx': os_traits.HW_CPU_X86_VMX,
|
||||
# We have to continue to support the old (generic) trait for the
|
||||
# Intel-specific vmx feature.
|
||||
'vmx': (os_traits.HW_CPU_X86_VMX, os_traits.HW_CPU_X86_INTEL_VMX),
|
||||
'xop': os_traits.HW_CPU_X86_XOP
|
||||
}
|
||||
|
||||
@ -577,11 +581,15 @@ def cpu_features_to_traits(features: ty.Set[str]) -> ty.Dict[str, bool]:
|
||||
"""Returns this driver's CPU traits dict where keys are trait names from
|
||||
CPU_TRAITS_MAPPING, values are boolean indicates whether the trait should
|
||||
be set in the provider tree.
|
||||
|
||||
:param features: A set of feature names (short, lowercase,
|
||||
CPU_TRAITS_MAPPING's keys).
|
||||
"""
|
||||
traits = {trait_name: False for trait_name in CPU_TRAITS_MAPPING.values()}
|
||||
for f in features:
|
||||
if f in CPU_TRAITS_MAPPING:
|
||||
traits[CPU_TRAITS_MAPPING[f]] = True
|
||||
traits = {}
|
||||
for feature_name, val in CPU_TRAITS_MAPPING.items():
|
||||
trait_tuple = val if isinstance(val, tuple) else (val,)
|
||||
for trait_name in trait_tuple:
|
||||
traits[trait_name] = feature_name in features
|
||||
|
||||
return traits
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user