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:
parent
f0ec6378c4
commit
e45f3b5d71
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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+).
|
Loading…
x
Reference in New Issue
Block a user