Remove support for Intel CMT events

The 4.14 kernel is sufficiently old in the tooth (Ubuntu 18.04 uses
4.15, RHEL 7.x has likely backported the fixes) that there are likely
not a great deal of users that could still use this broken feature if
they wanted to. Drop support for it almost entirely, retaining only a
warning to prevent accidental use.

Change-Id: Iad76bce128574dc2f86998ccf2a9c5e799c71313
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2020-07-14 10:06:12 +01:00
parent f0ec6378c4
commit e45f3b5d71
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)
@ -5688,38 +5683,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+).