Skip to content

Commit e45f3b5

Browse files
committed
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 <[email protected]>
1 parent f0ec637 commit e45f3b5

File tree

4 files changed

+39
-127
lines changed

4 files changed

+39
-127
lines changed

nova/conf/libvirt.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -783,15 +783,13 @@
783783
cfg.ListOpt('enabled_perf_events',
784784
default=[],
785785
help= """
786+
Performance events to monitor and collect statistics for.
787+
786788
This will allow you to specify a list of events to monitor low-level
787-
performance of guests, and collect related statsitics via the libvirt
788-
driver, which in turn uses the Linux kernel's `perf` infrastructure.
789+
performance of guests, and collect related statistics via the libvirt
790+
driver, which in turn uses the Linux kernel's ``perf`` infrastructure.
789791
With this config attribute set, Nova will generate libvirt guest XML to
790-
monitor the specified events. For more information, refer to the
791-
"Performance monitoring events" section here:
792-
https://libvirt.org/formatdomain.html#elementsPerf. And here:
793-
https://libvirt.org/html/libvirt-libvirt-domain.html -- look for
794-
``VIR_PERF_PARAM_*``
792+
monitor the specified events.
795793
796794
For example, to monitor the count of CPU cycles (total/elapsed) and the
797795
count of cache misses, enable them as follows::
@@ -800,12 +798,11 @@
800798
enabled_perf_events = cpu_clock, cache_misses
801799
802800
Possible values: A string list. The list of supported events can be
803-
found here: https://libvirt.org/formatdomain.html#elementsPerf.
801+
found `here`__. Note that Intel CMT events - ``cmt``, ``mbmbt`` and
802+
``mbml`` - are unsupported by recent Linux kernel versions (4.14+) and will be
803+
ignored by nova.
804804
805-
Note that support for Intel CMT events (`cmt`, `mbmbt`, `mbml`) is
806-
deprecated, and will be removed in the "Stein" release. That's because
807-
the upstream Linux kernel (from 4.14 onwards) has deleted support for
808-
Intel CMT, because it is broken by design.
805+
__ https://libvirt.org/formatdomain.html#elementsPerf.
809806
"""),
810807
cfg.IntOpt('num_pcie_ports',
811808
default=0,

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 9 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -8613,97 +8613,19 @@ def test_get_guest_memory_balloon_config_lxc(self):
86138613
break
86148614
self.assertTrue(no_exist)
86158615

8616-
@mock.patch('nova.virt.libvirt.driver.LOG.warning')
8617-
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
8618-
@mock.patch.object(host.Host, "get_capabilities")
8619-
def test_get_supported_perf_events_foo(self, mock_get_caps,
8620-
mock_min_version,
8621-
mock_warn):
8622-
self.flags(enabled_perf_events=['foo'], group='libvirt')
8623-
8624-
caps = vconfig.LibvirtConfigCaps()
8625-
caps.host = vconfig.LibvirtConfigCapsHost()
8626-
caps.host.cpu = vconfig.LibvirtConfigCPU()
8627-
caps.host.cpu.arch = fields.Architecture.X86_64
8628-
caps.host.topology = fakelibvirt.NUMATopology()
8616+
@mock.patch.object(libvirt_driver, 'LOG')
8617+
@mock.patch.object(
8618+
fakelibvirt, 'VIR_PERF_PARAM_CPU_CLOCK', 'cpu_clock', create=True)
8619+
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', 'cmt', create=True)
8620+
def test_get_supported_perf_events(self, mock_log):
8621+
self.flags(
8622+
enabled_perf_events=['cpu_clock', 'foo', 'cmt'], group='libvirt')
86298623

8630-
mock_get_caps.return_value = caps
86318624
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
86328625
events = drvr._get_supported_perf_events()
86338626

8634-
self.assertTrue(mock_warn.called)
8635-
self.assertEqual([], events)
8636-
8637-
@mock.patch.object(host.Host, "get_capabilities")
8638-
def _test_get_guest_with_perf(self, caps, events, mock_get_caps):
8639-
mock_get_caps.return_value = caps
8640-
8641-
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
8642-
drvr.init_host('test_perf')
8643-
instance_ref = objects.Instance(**self.test_instance)
8644-
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
8645-
8646-
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
8647-
instance_ref,
8648-
image_meta)
8649-
cfg = drvr._get_guest_config(instance_ref, [],
8650-
image_meta, disk_info)
8651-
8652-
self.assertEqual(events, cfg.perf_events)
8653-
8654-
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', True,
8655-
create=True)
8656-
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
8657-
def test_get_guest_with_perf_host_unsupported(self,
8658-
mock_min_version):
8659-
self.flags(enabled_perf_events=['cmt'], group='libvirt')
8660-
caps = vconfig.LibvirtConfigCaps()
8661-
caps.host = vconfig.LibvirtConfigCapsHost()
8662-
caps.host.cpu = vconfig.LibvirtConfigCPU()
8663-
caps.host.cpu.arch = fields.Architecture.X86_64
8664-
caps.host.topology = fakelibvirt.NUMATopology()
8665-
8666-
self._test_get_guest_with_perf(caps, [])
8667-
8668-
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_CMT', True,
8669-
create=True)
8670-
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_MBMT', True,
8671-
create=True)
8672-
@mock.patch.object(fakelibvirt, 'VIR_PERF_PARAM_MBML', True,
8673-
create=True)
8674-
@mock.patch.object(libvirt_driver.LOG, 'warning')
8675-
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
8676-
def test_intel_cmt_perf_deprecation_warning(self,
8677-
mock_min_version,
8678-
mock_warn):
8679-
perf_events = ['cmt', 'mbml', 'mbmt']
8680-
self.flags(enabled_perf_events=['cmt', 'mbml', 'mbmt'],
8681-
group='libvirt')
8682-
caps = vconfig.LibvirtConfigCaps()
8683-
caps.host = vconfig.LibvirtConfigCapsHost()
8684-
caps.host.cpu = vconfig.LibvirtConfigCPU()
8685-
caps.host.cpu.arch = fields.Architecture.X86_64
8686-
caps.host.topology = fakelibvirt.NUMATopology()
8687-
8688-
features = []
8689-
for f in ('cmt', 'mbm_local', 'mbm_total'):
8690-
feature = vconfig.LibvirtConfigGuestCPUFeature()
8691-
feature.name = f
8692-
feature.policy = fields.CPUFeaturePolicy.REQUIRE
8693-
features.append(feature)
8694-
8695-
caps.host.cpu.features = set(features)
8696-
self._test_get_guest_with_perf(caps, ['cmt', 'mbml', 'mbmt'])
8697-
warning_count = 0
8698-
call_args_list = mock_warn.call_args_list
8699-
for call in call_args_list:
8700-
# Call can be unpackaged as a tuple of args and kwargs
8701-
# so we want to check the first arg in the args list
8702-
if (len(call) == 2 and len(call[0]) == 2 and
8703-
call[0][1] in perf_events and
8704-
'Monitoring Intel CMT' in call[0][0]):
8705-
warning_count += 1
8706-
self.assertEqual(3, warning_count)
8627+
self.assertEqual(['cpu_clock'], events)
8628+
self.assertEqual(2, len(mock_log.warning.mock_calls))
87078629

87088630
def test_xml_and_uri_no_ramdisk_no_kernel(self):
87098631
instance_data = dict(self.test_instance)

nova/virt/libvirt/driver.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,6 @@ def repr_method(self):
248248

249249
LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_'
250250

251-
PERF_EVENTS_CPU_FLAG_MAPPING = {'cmt': 'cmt',
252-
'mbml': 'mbm_local',
253-
'mbmt': 'mbm_total',
254-
}
255-
256251
MIN_LIBVIRT_FILE_BACKED_DISCARD_VERSION = (4, 4, 0)
257252

258253
MIN_LIBVIRT_NATIVE_TLS_VERSION = (4, 4, 0)
@@ -5688,37 +5683,28 @@ def _check_uefi_support(self, hw_firmware_type):
56885683
caps.host.cpu.arch == fields.Architecture.AARCH64))
56895684

56905685
def _get_supported_perf_events(self):
5691-
5692-
if (len(CONF.libvirt.enabled_perf_events) == 0):
5686+
if not len(CONF.libvirt.enabled_perf_events):
56935687
return []
56945688

56955689
supported_events = []
5696-
host_cpu_info = self._get_cpu_info()
56975690
for event in CONF.libvirt.enabled_perf_events:
5698-
if self._supported_perf_event(event, host_cpu_info['features']):
5699-
supported_events.append(event)
5700-
return supported_events
5691+
libvirt_perf_event_name = LIBVIRT_PERF_EVENT_PREFIX + event.upper()
57015692

5702-
def _supported_perf_event(self, event, cpu_features):
5693+
if not hasattr(libvirt, libvirt_perf_event_name):
5694+
LOG.warning("Libvirt does not support event type '%s'.", event)
5695+
continue
57035696

5704-
libvirt_perf_event_name = LIBVIRT_PERF_EVENT_PREFIX + event.upper()
5697+
if event in ('cmt', 'mbml', 'mbmt'):
5698+
LOG.warning(
5699+
"Monitoring of Intel CMT `perf` event(s) '%s' is not "
5700+
"supported by recent Linux kernels; ignoring.",
5701+
event,
5702+
)
5703+
continue
57055704

5706-
if not hasattr(libvirt, libvirt_perf_event_name):
5707-
LOG.warning("Libvirt doesn't support event type %s.", event)
5708-
return False
5705+
supported_events.append(event)
57095706

5710-
if event in PERF_EVENTS_CPU_FLAG_MAPPING:
5711-
LOG.warning('Monitoring Intel CMT `perf` event(s) %s is '
5712-
'deprecated and will be removed in the "Stein" '
5713-
'release. It was broken by design in the '
5714-
'Linux kernel, so support for Intel CMT was '
5715-
'removed from Linux 4.14 onwards. Therefore '
5716-
'it is recommended to not enable them.',
5717-
event)
5718-
if PERF_EVENTS_CPU_FLAG_MAPPING[event] not in cpu_features:
5719-
LOG.warning("Host does not support event type %s.", event)
5720-
return False
5721-
return True
5707+
return supported_events
57225708

57235709
def _configure_guest_by_virt_type(self, guest, virt_type, caps, instance,
57245710
image_meta, flavor, root_device_name,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
upgrade:
3+
- |
4+
Intel CMT perf events - ``cmt``, ``mbmt``, and ``mbml`` - are no longer
5+
supported by the ``[libvirt] enabled_perf_events`` config option. These
6+
event types were broken by design and are not supported in recent Linux
7+
kernels (4.14+).

0 commit comments

Comments
 (0)