Merge "Remove support for Intel CMT events"
This commit is contained in:
commit
60fa0ec83b
@ -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)
|
||||
@ -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):
|
||||
|
@ -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