Merge "Remove support for Intel CMT events"

This commit is contained in:
Zuul 2020-09-03 01:59:22 +00:00 committed by Gerrit Code Review
commit 60fa0ec83b
4 changed files with 42 additions and 130 deletions

View File

@ -783,15 +783,13 @@ restricting flavors via host aggregates.
cfg.ListOpt('enabled_perf_events',
default=[],
help= """
Performance events to monitor and collect statistics for.
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.
performance of guests, and collect related statistics 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_*``
monitor the specified events.
For example, to monitor the count of CPU cycles (total/elapsed) and the
count of cache misses, enable them as follows::
@ -800,12 +798,11 @@ count of cache misses, enable them as follows::
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.
found `here`__. Note that Intel CMT events - ``cmt``, ``mbmbt`` and
``mbml`` - are unsupported by recent Linux kernel versions (4.14+) and will be
ignored by nova.
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.
__ https://libvirt.org/formatdomain.html#elementsPerf.
"""),
cfg.IntOpt('num_pcie_ports',
default=0,

View File

@ -8613,97 +8613,19 @@ class LibvirtConnTestCase(test.NoDBTestCase,
break
self.assertTrue(no_exist)
@mock.patch('nova.virt.libvirt.driver.LOG.warning')
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
@mock.patch.object(host.Host, "get_capabilities")
def test_get_supported_perf_events_foo(self, mock_get_caps,
mock_min_version,
mock_warn):
self.flags(enabled_perf_events=['foo'], group='libvirt')
@mock.patch.object(libvirt_driver, 'LOG')
@mock.patch.object(
fakelibvirt, 'VIR_PERF_PARAM_CPU_CLOCK', 'cpu_clock', create=True)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', 'cmt', create=True)
def test_get_supported_perf_events(self, mock_log):
self.flags(
enabled_perf_events=['cpu_clock', 'foo', 'cmt'], 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()
mock_get_caps.return_value = caps
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
events = drvr._get_supported_perf_events()
self.assertTrue(mock_warn.called)
self.assertEqual([], events)
@mock.patch.object(host.Host, "get_capabilities")
def _test_get_guest_with_perf(self, caps, events, mock_get_caps):
mock_get_caps.return_value = caps
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
drvr.init_host('test_perf')
instance_ref = objects.Instance(**self.test_instance)
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
image_meta)
cfg = drvr._get_guest_config(instance_ref, [],
image_meta, disk_info)
self.assertEqual(events, cfg.perf_events)
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', True,
create=True)
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
def test_get_guest_with_perf_host_unsupported(self,
mock_min_version):
self.flags(enabled_perf_events=['cmt'], 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()
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)
self.assertEqual(['cpu_clock'], events)
self.assertEqual(2, len(mock_log.warning.mock_calls))
def test_xml_and_uri_no_ramdisk_no_kernel(self):
instance_data = dict(self.test_instance)

View File

@ -248,11 +248,6 @@ VGPU_RESOURCE_SEMAPHORE = 'vgpu_resources'
LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_'
PERF_EVENTS_CPU_FLAG_MAPPING = {'cmt': 'cmt',
'mbml': 'mbm_local',
'mbmt': 'mbm_total',
}
MIN_LIBVIRT_FILE_BACKED_DISCARD_VERSION = (4, 4, 0)
MIN_LIBVIRT_NATIVE_TLS_VERSION = (4, 4, 0)
@ -5686,38 +5681,29 @@ class LibvirtDriver(driver.ComputeDriver):
caps.host.cpu.arch == fields.Architecture.AARCH64))
def _get_supported_perf_events(self):
if (len(CONF.libvirt.enabled_perf_events) == 0):
if not len(CONF.libvirt.enabled_perf_events):
return []
supported_events = []
host_cpu_info = self._get_cpu_info()
for event in CONF.libvirt.enabled_perf_events:
if self._supported_perf_event(event, host_cpu_info['features']):
supported_events.append(event)
libvirt_perf_event_name = LIBVIRT_PERF_EVENT_PREFIX + event.upper()
if not hasattr(libvirt, libvirt_perf_event_name):
LOG.warning("Libvirt does not support event type '%s'.", event)
continue
if event in ('cmt', 'mbml', 'mbmt'):
LOG.warning(
"Monitoring of Intel CMT `perf` event(s) '%s' is not "
"supported by recent Linux kernels; ignoring.",
event,
)
continue
supported_events.append(event)
return supported_events
def _supported_perf_event(self, event, cpu_features):
libvirt_perf_event_name = LIBVIRT_PERF_EVENT_PREFIX + event.upper()
if not hasattr(libvirt, libvirt_perf_event_name):
LOG.warning("Libvirt doesn't 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,
image_meta, flavor, root_device_name,
sev_enabled):

View File

@ -0,0 +1,7 @@
---
upgrade:
- |
Intel CMT perf events - ``cmt``, ``mbmt``, and ``mbml`` - are no longer
supported by the ``[libvirt] enabled_perf_events`` config option. These
event types were broken by design and are not supported in recent Linux
kernels (4.14+).