Merge "libvirt: Deprecate support for monitoring Intel CMT `perf` events"

This commit is contained in:
Zuul 2018-05-25 03:00:33 +00:00 committed by Gerrit Code Review
commit e4a2ebafe1
4 changed files with 90 additions and 43 deletions

View File

@ -696,17 +696,29 @@ Possible cache modes:
cfg.ListOpt('enabled_perf_events',
default=[],
help= """
This is a performance event list which could be used as monitor. These events
will be passed to libvirt domain xml while creating a new instances.
Then event statistics data can be collected from libvirt. The minimum
libvirt version is 2.0.0. For more information about `Performance monitoring
events`, refer https://libvirt.org/formatdomain.html#elementsPerf .
This will allow you to specify a list of events to monitor low-level
performance of guests, and collect related statsitics via the libvirt
driver, which in turn uses the Linux kernel's `perf` infrastructure.
With this config attribute set, Nova will generate libvirt guest XML to
monitor the specified events. For more information, refer to the
"Performance monitoring events" section here:
https://libvirt.org/formatdomain.html#elementsPerf. And here:
https://libvirt.org/html/libvirt-libvirt-domain.html -- look for
``VIR_PERF_PARAM_*``
Possible values:
* A string list. For example: ``enabled_perf_events = cmt, mbml, mbmt``
The supported events list can be found in
https://libvirt.org/html/libvirt-libvirt-domain.html ,
which you may need to search key words ``VIR_PERF_PARAM_*``
For example, to monitor the count of CPU cycles (total/elapsed) and the
count of cache misses, enable them as follows::
[libvirt]
enabled_perf_events = cpu_clock, cache_misses
Possible values: A string list. The list of supported events can be
found here: https://libvirt.org/formatdomain.html#elementsPerf.
Note that support for Intel CMT events (`cmt`, `mbmbt`, `mbml`) is
deprecated, and will be removed in the "Stein" release. That's because
the upstream Linux kernel (from 4.14 onwards) has deleted support for
Intel CMT, because it is broken by design.
"""),
cfg.IntOpt('num_pcie_ports',
default=0,

View File

@ -6567,34 +6567,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(events, cfg.perf_events)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', True,
create=True)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_MBMT', True,
create=True)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_MBML', True,
create=True)
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
def test_get_guest_with_perf_supported(self,
mock_min_version):
self.flags(enabled_perf_events=['cmt', 'mbml', 'mbmt'],
group='libvirt')
caps = vconfig.LibvirtConfigCaps()
caps.host = vconfig.LibvirtConfigCapsHost()
caps.host.cpu = vconfig.LibvirtConfigCPU()
caps.host.cpu.arch = fields.Architecture.X86_64
caps.host.topology = fakelibvirt.NUMATopology()
features = []
for f in ('cmt', 'mbm_local', 'mbm_total'):
feature = vconfig.LibvirtConfigGuestCPUFeature()
feature.name = f
feature.policy = fields.CPUFeaturePolicy.REQUIRE
features.append(feature)
caps.host.cpu.features = set(features)
self._test_get_guest_with_perf(caps, ['cmt', 'mbml', 'mbmt'])
@mock.patch.object(host.Host, 'has_min_version')
def test_get_guest_with_perf_libvirt_unsupported(self, mock_min_version):
@ -6627,6 +6599,46 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self._test_get_guest_with_perf(caps, [])
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', True,
create=True)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_MBMT', True,
create=True)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_MBML', True,
create=True)
@mock.patch.object(libvirt_driver.LOG, 'warning')
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
def test_intel_cmt_perf_deprecation_warning(self,
mock_min_version,
mock_warn):
perf_events = ['cmt', 'mbml', 'mbmt']
self.flags(enabled_perf_events=['cmt', 'mbml', 'mbmt'],
group='libvirt')
caps = vconfig.LibvirtConfigCaps()
caps.host = vconfig.LibvirtConfigCapsHost()
caps.host.cpu = vconfig.LibvirtConfigCPU()
caps.host.cpu.arch = fields.Architecture.X86_64
caps.host.topology = fakelibvirt.NUMATopology()
features = []
for f in ('cmt', 'mbm_local', 'mbm_total'):
feature = vconfig.LibvirtConfigGuestCPUFeature()
feature.name = f
feature.policy = fields.CPUFeaturePolicy.REQUIRE
features.append(feature)
caps.host.cpu.features = set(features)
self._test_get_guest_with_perf(caps, ['cmt', 'mbml', 'mbmt'])
warning_count = 0
call_args_list = mock_warn.call_args_list
for call in call_args_list:
# Call can be unpackaged as a tuple of args and kwargs
# so we want to check the first arg in the args list
if (len(call) == 2 and len(call[0]) == 2 and
call[0][1] in perf_events and
'Monitoring Intel CMT' in call[0][0]):
warning_count += 1
self.assertEqual(3, warning_count)
def test_xml_and_uri_no_ramdisk_no_kernel(self):
instance_data = dict(self.test_instance)
self._check_xml_and_uri(instance_data,

View File

@ -4740,11 +4740,17 @@ class LibvirtDriver(driver.ComputeDriver):
LOG.warning("Libvirt doesn't support event type %s.", event)
return False
if (event in PERF_EVENTS_CPU_FLAG_MAPPING
and PERF_EVENTS_CPU_FLAG_MAPPING[event] not in cpu_features):
LOG.warning("Host does not support event type %s.", event)
return False
if event in PERF_EVENTS_CPU_FLAG_MAPPING:
LOG.warning('Monitoring Intel CMT `perf` event(s) %s is '
'deprecated and will be removed in the "Stein" '
'release. It was broken by design in the '
'Linux kernel, so support for Intel CMT was '
'removed from Linux 4.14 onwards. Therefore '
'it is recommended to not enable them.',
event)
if PERF_EVENTS_CPU_FLAG_MAPPING[event] not in cpu_features:
LOG.warning("Host does not support event type %s.", event)
return False
return True
def _configure_guest_by_virt_type(self, guest, virt_type, caps, instance,

View File

@ -0,0 +1,17 @@
---
deprecations:
- |
Support to monitor performance events for Intel CMT (Cache
Monitoring Technology, or "CQM" in Linux kernel parlance) -- namely
``cmt``, ``mbm_local`` and ``mbm_total`` -- via the config attribute
``[libvirt]/enabled_perf_events`` is now *deprecated* from Nova, and
will be *removed* in the "Stein" release. Otherwise, if you have
enabled those events, and upgraded to Linux kernel 4.14 (or suitable
downstream version), it will result in instances failing to boot.
That is because the Linux kernel has deleted the `perf` framework
integration with Intel CMT, as the feature was broken by design --
an incompatibility between Linux's `perf` infrastructure and Intel
CMT. It was removed in upstream Linux version v4.14; but bear in
mind that downstream Linux distributions with lower kernel versions
than 4.14 have backported the said change.