From 333391f114a7be4f10b1eb6e5f0fe571efd87f7d Mon Sep 17 00:00:00 2001 From: Disha Goel Date: Thu, 5 Sep 2024 20:15:26 +0530 Subject: [PATCH] perf: fix perf tests to support generic compat pmu perf_c2c, perf_mem tests give error incase perf mem command fails when events are not available. Fix it by adding ignore_status check so test cancels. Similarly perf_json test gives error when pmu events are not present when generic compat pmu is registered. Modify the code to cancel when events are not present. Also moved kernel building part after perf list check to avoid kernel build when not required. Added event raw codes for generic compat pmu for perf_genericevents test. Modified perf_pmu:test_cpu_event_count by removing hardcoded number, instead just check for presence of events. perf_pmu:test_caps_feat fails on older distros where file is not present. Modified the code to check for caps file presence instead of checking for P10/P11. Add a check to find pmu events presence before running perf_rawevents test. Signed-off-by: Disha Goel --- perf/perf_c2c.py | 2 +- perf/perf_genericevents.py | 26 ++++++++++---------- perf/perf_genericevents.py.data/raw_code.cfg | 14 +++++++++++ perf/perf_json.py | 22 +++++++++-------- perf/perf_mem.py | 2 +- perf/perf_pmu.py | 17 ++++++------- perf/perf_rawevents.py | 5 ++++ 7 files changed, 54 insertions(+), 34 deletions(-) diff --git a/perf/perf_c2c.py b/perf/perf_c2c.py index 67bc3c782..44a6d673c 100644 --- a/perf/perf_c2c.py +++ b/perf/perf_c2c.py @@ -56,7 +56,7 @@ def setUp(self): self.cancel('%s is needed for the test to be run' % package) # Check for c2c is available in the system. - output = process.run('perf mem record -e list').stderr.decode("utf-8") + output = process.run('perf mem record -e list', ignore_status=True).stderr.decode("utf-8") if 'ldlat-stores' in output or 'ldlat-loads' in output: self.log.info("perf c2c is available") else: diff --git a/perf/perf_genericevents.py b/perf/perf_genericevents.py index 0fbf20b6d..46c468b8f 100755 --- a/perf/perf_genericevents.py +++ b/perf/perf_genericevents.py @@ -20,7 +20,7 @@ import os import configparser from avocado import Test -from avocado.utils import genio, cpu +from avocado.utils import cpu, process class test_generic_events(Test): @@ -36,18 +36,18 @@ def read_generic_events(self): parser = configparser.ConfigParser() parser.optionxform = str parser.read(self.get_data('raw_code.cfg')) - cpu_info = genio.read_file("/proc/cpuinfo") - for line in cpu_info.splitlines(): - if 'revision' in line: - self.rev = (line.split(':')[1]) - if '004b' in self.rev: - self.generic_events = dict(parser.items('POWER8')) - elif '004e' in self.rev: - self.generic_events = dict(parser.items('POWER9')) - elif '0080' in self.rev or '0082' in self.rev: - self.generic_events = dict(parser.items('POWER10')) - else: - self.cancel("Processor is not supported: %s" % cpu_info) + pmu_registered = process.system_output("journalctl -k|grep -i performance", + shell=True).decode().strip().lower() + pmu_event_mapping = {'generic_compat': 'GENERIC_COMPAT_PMU', + 'isav3': 'GENERIC_COMPAT_PMU', 'power8': 'POWER8', + 'power9': 'POWER9', 'power10': 'POWER10', + 'power11': 'POWER10'} + for pmu, event_type in pmu_event_mapping.items(): + if pmu in pmu_registered: + self.generic_events = dict(parser.items(event_type)) + return + self.cancel("Processor is not supported: %s" % pmu_registered) + self.arch = cpu.get_arch() self.vendor = cpu.get_vendor() if 'amd' in self.vendor: diff --git a/perf/perf_genericevents.py.data/raw_code.cfg b/perf/perf_genericevents.py.data/raw_code.cfg index edbdd5f32..6cc21f531 100644 --- a/perf/perf_genericevents.py.data/raw_code.cfg +++ b/perf/perf_genericevents.py.data/raw_code.cfg @@ -1,3 +1,17 @@ +[GENERIC_COMPAT_PMU] +cpu-cycles = 0x600f4 +instructions = 0x500fa +stalled-cycles-frontend = 0x100f8 +branch-misses = 0x400f6 +cache-misses = 0x400f0 +L1-dcache-load-misses = 0x400f0 +L1-dcache-store-misses = 0x300f0 +L1-icache-load-misses = 0x200fc +LLC-load-misses = 0x300fe +branch-load-misses = 0x400f6 +dTLB-load-misses = 0x300fc +iTLB-load-misses = 0x400fc + [POWER8] cpu-cycles = 0x1e stalled-cycles-frontend = 0x100f8 diff --git a/perf/perf_json.py b/perf/perf_json.py index c04acd2f4..467dae642 100644 --- a/perf/perf_json.py +++ b/perf/perf_json.py @@ -72,6 +72,18 @@ def setUp(self): if 'ppc64' not in detected_distro.arch: self.cancel("Processor is not PowerPC") + # Collect all pmu events from perf list and json files + self.perf_list_pmu_events = set() + self.json_pmu_events = set() + self.json_event_info = {} + + output = process.system_output("perf list --raw-dump pmu", shell=True) + for ln in output.decode().split(): + if ln.startswith('pm_') and ln not in ("hv_24x7" or "hv_gpci"): + self.perf_list_pmu_events.add(ln) + if not self.perf_list_pmu_events: + self.cancel("No PMU events found. Skipping the test.") + deps = ['gcc', 'make', 'perf'] if 'Ubuntu' in detected_distro.name: deps.extend(['linux-tools-common', 'linux-tools-%s' @@ -101,16 +113,6 @@ def setUp(self): self.testdir += '%s/' % rev_to_power[self.rev] self.sourcedir = os.path.join(self.buldir, self.testdir) - # Collect all pmu events from perf list and json files - self.perf_list_pmu_events = set() - self.json_pmu_events = set() - self.json_event_info = {} - - output = process.system_output("perf list --raw-dump pmu", shell=True) - for ln in output.decode().split(): - if ln.startswith('pm_') and ln not in ("hv_24x7" or "hv_gpci"): - self.perf_list_pmu_events.add(ln) - # Clear the dmesg to capture the delta at the end of the test. dmesg.clear_dmesg() diff --git a/perf/perf_mem.py b/perf/perf_mem.py index d27baa4f9..e14ab616f 100644 --- a/perf/perf_mem.py +++ b/perf/perf_mem.py @@ -52,7 +52,7 @@ def setUp(self): self.cancel('%s is needed for the test to be run' % package) # Check for mem is available in the system. - output = process.run('perf mem record -e list').stderr.decode("utf-8") + output = process.run('perf mem record -e list', ignore_status=True).stderr.decode("utf-8") if 'ldlat-stores' in output or 'ldlat-loads' in output: self.log.info("perf mem is available") else: diff --git a/perf/perf_pmu.py b/perf/perf_pmu.py index ba335edf4..94ffd0e48 100644 --- a/perf/perf_pmu.py +++ b/perf/perf_pmu.py @@ -202,9 +202,8 @@ def _check_count(self, event_type): sys_fs_events = os.listdir( os.path.join(base_dir, event_type, 'events')) - if len(sys_fs_events) < 21: - self.fail("%s events folder contains less than 21 entries" - % event_type) + if not sys_fs_events: + self.fail("no events found in %s events folder" % event_type) self.log.info("%s events count = %s" % (event_type, len(sys_fs_events))) @@ -235,13 +234,13 @@ def test_write_sysfs_events(self): self._remove_temp_user() def test_caps_feat(self): - modes = ['power10', 'power11'] - if self.model in modes: - cmd = "cat /sys/bus/event_source/devices/cpu/caps/pmu_name" - sysfs_value = process.system_output(cmd, shell=True).decode() - self.log.info(" Sysfs caps version : %s " % sysfs_value) + caps_filepath = "/sys/bus/event_source/devices/cpu/caps/pmu_name" + if os.path.isfile(caps_filepath): + pmu_name = process.system_output(f'cat {caps_filepath}', + shell=True).decode() + self.log.info("Sysfs pmu registered: %s" % pmu_name) else: - self.cancel("This test is supported only for Power10 and above") + self.cancel("Caps file not found, skipping test") @skipIf(IS_POWER_NV or IS_KVM_GUEST, "This test is for PowerVM") def test_hv_24x7_event_count(self): diff --git a/perf/perf_rawevents.py b/perf/perf_rawevents.py index 88f0b1554..e34b83069 100644 --- a/perf/perf_rawevents.py +++ b/perf/perf_rawevents.py @@ -67,6 +67,11 @@ def setUp(self): if not smm.check_installed(package) and not smm.install(package): self.cancel('%s is needed for the test to be run' % package) + output = process.system_output("perf list --raw-dump pmu|grep pm_*", + shell=True, ignore_status=True) + if not output: + self.cancel("No PMU events found. Skipping the test") + revisions_to_test = ['004b', '004e', '0080', '0082'] for rev in revisions_to_test: for filename in [f'name_events_{rev}', f'raw_codes_{rev}']: