Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf jevents: Autogenerate empty-pmu-events.c

empty-pmu-events.c exists so that builds may occur without python
being installed on a system. Manually updating empty-pmu-events.c to
be in sync with jevents.py is a pain, let's use jevents.py to generate
empty-pmu-events.c.

1) change jevents.py so that an arch and model of none cause
generation of a pmu-events.c without any json. Add a SPDX and
autogenerated warning to the start of the file.

2) change Build so that if a generated pmu-events.c for arch none and
model none doesn't match empty-pmu-events.c the build fails with a
cat of the differences. Update Makefile.perf to clean up the files
used for this.

3) update empty-pmu-events.c to match the output of jevents.py with
arch and mode of none.

Committer notes:

The firtst paragraph is confusing, so I asked and Ian further clarified:

---
The requirement for python hasn't changed.

Case 1: no python or NO_JEVENTS=1
Build happens using empty-pmu-events.c that is checked in, no python
is required.

Case 2: python
pmu-events.c is created by jevents.py (requiring python) and then built.
This change adds a step where the empty-pmu-events.c is created using
jevents.py and that file is diffed against the checked in version.

This stops the checked in empty-pmu-events.c diverging if changes are
made to jevents.py. If the diff causes the build to fail then you just
copy the diff empty-pmu-events.c over the checked in one.
---

Reviewed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Oliver Sang <oliver.sang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Philip Li <philip.li@intel.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Xu Yang <xu.yang_2@nxp.com>
Link: https://lore.kernel.org/r/20240730191744.3097329-3-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
0fe881f1 ea59b70a

+558 -348
+2
tools/perf/Makefile.perf
··· 1277 1277 $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ 1278 1278 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ 1279 1279 $(OUTPUT)pmu-events/pmu-events.c \ 1280 + $(OUTPUT)pmu-events/test-empty-pmu-events.c \ 1281 + $(OUTPUT)pmu-events/empty-pmu-events.log \ 1280 1282 $(OUTPUT)pmu-events/metric_test.log \ 1281 1283 $(OUTPUT)$(fadvise_advice_array) \ 1282 1284 $(OUTPUT)$(fsconfig_arrays) \
+11 -1
tools/perf/pmu-events/Build
··· 11 11 EMPTY_PMU_EVENTS_C = pmu-events/empty-pmu-events.c 12 12 PMU_EVENTS_C = $(OUTPUT)pmu-events/pmu-events.c 13 13 METRIC_TEST_LOG = $(OUTPUT)pmu-events/metric_test.log 14 + TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c 15 + EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log 14 16 15 17 ifeq ($(JEVENTS_ARCH),) 16 18 JEVENTS_ARCH=$(SRCARCH) ··· 33 31 $(call rule_mkdir) 34 32 $(Q)$(call echo-cmd,test)$(PYTHON) $< 2> $@ || (cat $@ && false) 35 33 36 - $(PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) 34 + $(TEST_EMPTY_PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) 35 + $(call rule_mkdir) 36 + $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none pmu-events/arch $@ 37 + 38 + $(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C) 39 + $(call rule_mkdir) 40 + $(Q)$(call echo-cmd,test)diff -u $? 2> $@ || (cat $@ && false) 41 + 42 + $(PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) $(EMPTY_PMU_EVENTS_TEST_LOG) 37 43 $(call rule_mkdir) 38 44 $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) pmu-events/arch $@ 39 45 endif
+540 -346
tools/perf/pmu-events/empty-pmu-events.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * An empty pmu-events.c file used when there is no architecture json files in 4 - * arch or when the jevents.py script cannot be run. 5 - * 6 - * The test cpu/soc is provided for testing. 7 - */ 8 - #include "pmu-events/pmu-events.h" 1 + 2 + /* SPDX-License-Identifier: GPL-2.0 */ 3 + /* THIS FILE WAS AUTOGENERATED BY jevents.py arch=none model=none ! */ 4 + 5 + #include <pmu-events/pmu-events.h> 9 6 #include "util/header.h" 10 7 #include "util/pmu.h" 11 8 #include <string.h> 12 9 #include <stddef.h> 13 10 14 - static const struct pmu_event pmu_events__test_soc_cpu[] = { 15 - { 16 - .name = "l3_cache_rd", 17 - .event = "event=0x40", 18 - .desc = "L3 cache access, read", 19 - .topic = "cache", 20 - .long_desc = "Attributable Level 3 cache access, read", 21 - }, 22 - { 23 - .name = "segment_reg_loads.any", 24 - .event = "event=0x6,period=200000,umask=0x80", 25 - .desc = "Number of segment register loads", 26 - .topic = "other", 27 - }, 28 - { 29 - .name = "dispatch_blocked.any", 30 - .event = "event=0x9,period=200000,umask=0x20", 31 - .desc = "Memory cluster signals to block micro-op dispatch for any reason", 32 - .topic = "other", 33 - }, 34 - { 35 - .name = "eist_trans", 36 - .event = "event=0x3a,period=200000,umask=0x0", 37 - .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", 38 - .topic = "other", 39 - }, 40 - { 41 - .name = "uncore_hisi_ddrc.flux_wcmd", 42 - .event = "event=0x2", 43 - .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", 44 - .topic = "uncore", 45 - .long_desc = "DDRC write commands", 46 - .pmu = "hisi_sccl,ddrc", 47 - }, 48 - { 49 - .name = "unc_cbo_xsnp_response.miss_eviction", 50 - .event = "event=0x22,umask=0x81", 51 - .desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core. Unit: uncore_cbox ", 52 - .topic = "uncore", 53 - .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", 54 - .pmu = "uncore_cbox", 55 - }, 56 - { 57 - .name = "event-hyphen", 58 - .event = "event=0xe0,umask=0x00", 59 - .desc = "UNC_CBO_HYPHEN. Unit: uncore_cbox ", 60 - .topic = "uncore", 61 - .long_desc = "UNC_CBO_HYPHEN", 62 - .pmu = "uncore_cbox", 63 - }, 64 - { 65 - .name = "event-two-hyph", 66 - .event = "event=0xc0,umask=0x00", 67 - .desc = "UNC_CBO_TWO_HYPH. Unit: uncore_cbox ", 68 - .topic = "uncore", 69 - .long_desc = "UNC_CBO_TWO_HYPH", 70 - .pmu = "uncore_cbox", 71 - }, 72 - { 73 - .name = "uncore_hisi_l3c.rd_hit_cpipe", 74 - .event = "event=0x7", 75 - .desc = "Total read hits. Unit: hisi_sccl,l3c ", 76 - .topic = "uncore", 77 - .long_desc = "Total read hits", 78 - .pmu = "hisi_sccl,l3c", 79 - }, 80 - { 81 - .name = "uncore_imc_free_running.cache_miss", 82 - .event = "event=0x12", 83 - .desc = "Total cache misses. Unit: uncore_imc_free_running ", 84 - .topic = "uncore", 85 - .long_desc = "Total cache misses", 86 - .pmu = "uncore_imc_free_running", 87 - }, 88 - { 89 - .name = "uncore_imc.cache_hits", 90 - .event = "event=0x34", 91 - .desc = "Total cache hits. Unit: uncore_imc ", 92 - .topic = "uncore", 93 - .long_desc = "Total cache hits", 94 - .pmu = "uncore_imc", 95 - }, 96 - { 97 - .name = "bp_l1_btb_correct", 98 - .event = "event=0x8a", 99 - .desc = "L1 BTB Correction", 100 - .topic = "branch", 101 - }, 102 - { 103 - .name = "bp_l2_btb_correct", 104 - .event = "event=0x8b", 105 - .desc = "L2 BTB Correction", 106 - .topic = "branch", 107 - }, 108 - { 109 - .name = 0, 110 - .event = 0, 111 - .desc = 0, 112 - }, 11 + struct compact_pmu_event { 12 + int offset; 113 13 }; 114 14 115 - static const struct pmu_metric pmu_metrics__test_soc_cpu[] = { 116 - { 117 - .metric_expr = "1 / IPC", 118 - .metric_name = "CPI", 119 - }, 120 - { 121 - .metric_expr = "inst_retired.any / cpu_clk_unhalted.thread", 122 - .metric_name = "IPC", 123 - .metric_group = "group1", 124 - }, 125 - { 126 - .metric_expr = "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * " 127 - "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))", 128 - .metric_name = "Frontend_Bound_SMT", 129 - }, 130 - { 131 - .metric_expr = "l1d\\-loads\\-misses / inst_retired.any", 132 - .metric_name = "dcache_miss_cpi", 133 - }, 134 - { 135 - .metric_expr = "l1i\\-loads\\-misses / inst_retired.any", 136 - .metric_name = "icache_miss_cycles", 137 - }, 138 - { 139 - .metric_expr = "(dcache_miss_cpi + icache_miss_cycles)", 140 - .metric_name = "cache_miss_cycles", 141 - .metric_group = "group1", 142 - }, 143 - { 144 - .metric_expr = "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit", 145 - .metric_name = "DCache_L2_All_Hits", 146 - }, 147 - { 148 - .metric_expr = "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + " 149 - "l2_rqsts.pf_miss + l2_rqsts.rfo_miss", 150 - .metric_name = "DCache_L2_All_Miss", 151 - }, 152 - { 153 - .metric_expr = "DCache_L2_All_Hits + DCache_L2_All_Miss", 154 - .metric_name = "DCache_L2_All", 155 - }, 156 - { 157 - .metric_expr = "d_ratio(DCache_L2_All_Hits, DCache_L2_All)", 158 - .metric_name = "DCache_L2_Hits", 159 - }, 160 - { 161 - .metric_expr = "d_ratio(DCache_L2_All_Miss, DCache_L2_All)", 162 - .metric_name = "DCache_L2_Misses", 163 - }, 164 - { 165 - .metric_expr = "ipc + M2", 166 - .metric_name = "M1", 167 - }, 168 - { 169 - .metric_expr = "ipc + M1", 170 - .metric_name = "M2", 171 - }, 172 - { 173 - .metric_expr = "1/M3", 174 - .metric_name = "M3", 175 - }, 176 - { 177 - .metric_expr = "64 * l1d.replacement / 1000000000 / duration_time", 178 - .metric_name = "L1D_Cache_Fill_BW", 179 - }, 180 - { 181 - .metric_expr = 0, 182 - .metric_name = 0, 183 - }, 15 + struct pmu_table_entry { 16 + const struct compact_pmu_event *entries; 17 + uint32_t num_entries; 18 + struct compact_pmu_event pmu_name; 184 19 }; 20 + 21 + static const char *const big_c_string = 22 + /* offset=0 */ "default_core\000" 23 + /* offset=13 */ "bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=0x8a\000\00000\000\000" 24 + /* offset=72 */ "bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=0x8b\000\00000\000\000" 25 + /* offset=131 */ "l3_cache_rd\000cache\000L3 cache access, read\000event=0x40\000\00000\000Attributable Level 3 cache access, read\000" 26 + /* offset=226 */ "segment_reg_loads.any\000other\000Number of segment register loads\000event=6,period=200000,umask=0x80\000\00000\000\000" 27 + /* offset=325 */ "dispatch_blocked.any\000other\000Memory cluster signals to block micro-op dispatch for any reason\000event=9,period=200000,umask=0x20\000\00000\000\000" 28 + /* offset=455 */ "eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions\000event=0x3a,period=200000\000\00000\000\000" 29 + /* offset=570 */ "hisi_sccl,ddrc\000" 30 + /* offset=585 */ "uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\000event=2\000\00000\000DDRC write commands\000" 31 + /* offset=671 */ "uncore_cbox\000" 32 + /* offset=683 */ "unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000event=0x22,umask=0x81\000\00000\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000" 33 + /* offset=914 */ "event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=0xe0\000\00000\000UNC_CBO_HYPHEN\000" 34 + /* offset=979 */ "event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=0xc0\000\00000\000UNC_CBO_TWO_HYPH\000" 35 + /* offset=1050 */ "hisi_sccl,l3c\000" 36 + /* offset=1064 */ "uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000event=7\000\00000\000Total read hits\000" 37 + /* offset=1144 */ "uncore_imc_free_running\000" 38 + /* offset=1168 */ "uncore_imc_free_running.cache_miss\000uncore\000Total cache misses\000event=0x12\000\00000\000Total cache misses\000" 39 + /* offset=1263 */ "uncore_imc\000" 40 + /* offset=1274 */ "uncore_imc.cache_hits\000uncore\000Total cache hits\000event=0x34\000\00000\000Total cache hits\000" 41 + /* offset=1352 */ "uncore_sys_ddr_pmu\000" 42 + /* offset=1371 */ "sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\000event=0x2b\000v8\00000\000\000" 43 + /* offset=1444 */ "uncore_sys_ccn_pmu\000" 44 + /* offset=1463 */ "sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\000config=0x2c\0000x01\00000\000\000" 45 + /* offset=1537 */ "uncore_sys_cmn_pmu\000" 46 + /* offset=1556 */ "sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache misses in first lookup result (high priority)\000eventid=1,type=5\000(434|436|43c|43a).*\00000\000\000" 47 + /* offset=1696 */ "CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000" 48 + /* offset=1718 */ "IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\000\000\000\000\000\000\000\00000" 49 + /* offset=1781 */ "Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000" 50 + /* offset=1947 */ "dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000" 51 + /* offset=2011 */ "icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000" 52 + /* offset=2078 */ "cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_cycles\000\000\000\000\000\000\000\00000" 53 + /* offset=2149 */ "DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000" 54 + /* offset=2243 */ "DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\000\000\000\000\000\000\00000" 55 + /* offset=2377 */ "DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\000\000\000\000\000\000\000\00000" 56 + /* offset=2441 */ "DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_All)\000\000\000\000\000\000\000\00000" 57 + /* offset=2509 */ "DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2_All)\000\000\000\000\000\000\000\00000" 58 + /* offset=2579 */ "M1\000\000ipc + M2\000\000\000\000\000\000\000\00000" 59 + /* offset=2601 */ "M2\000\000ipc + M1\000\000\000\000\000\000\000\00000" 60 + /* offset=2623 */ "M3\000\0001 / M3\000\000\000\000\000\000\000\00000" 61 + /* offset=2643 */ "L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duration_time\000\000\000\000\000\000\000\00000" 62 + ; 63 + 64 + static const struct compact_pmu_event pmu_events__test_soc_cpu_default_core[] = { 65 + { 13 }, /* bp_l1_btb_correct\000branch\000L1 BTB Correction\000event=0x8a\000\00000\000\000 */ 66 + { 72 }, /* bp_l2_btb_correct\000branch\000L2 BTB Correction\000event=0x8b\000\00000\000\000 */ 67 + { 325 }, /* dispatch_blocked.any\000other\000Memory cluster signals to block micro-op dispatch for any reason\000event=9,period=200000,umask=0x20\000\00000\000\000 */ 68 + { 455 }, /* eist_trans\000other\000Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions\000event=0x3a,period=200000\000\00000\000\000 */ 69 + { 131 }, /* l3_cache_rd\000cache\000L3 cache access, read\000event=0x40\000\00000\000Attributable Level 3 cache access, read\000 */ 70 + { 226 }, /* segment_reg_loads.any\000other\000Number of segment register loads\000event=6,period=200000,umask=0x80\000\00000\000\000 */ 71 + }; 72 + static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_ddrc[] = { 73 + { 585 }, /* uncore_hisi_ddrc.flux_wcmd\000uncore\000DDRC write commands\000event=2\000\00000\000DDRC write commands\000 */ 74 + }; 75 + static const struct compact_pmu_event pmu_events__test_soc_cpu_hisi_sccl_l3c[] = { 76 + { 1064 }, /* uncore_hisi_l3c.rd_hit_cpipe\000uncore\000Total read hits\000event=7\000\00000\000Total read hits\000 */ 77 + }; 78 + static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_cbox[] = { 79 + { 914 }, /* event-hyphen\000uncore\000UNC_CBO_HYPHEN\000event=0xe0\000\00000\000UNC_CBO_HYPHEN\000 */ 80 + { 979 }, /* event-two-hyph\000uncore\000UNC_CBO_TWO_HYPH\000event=0xc0\000\00000\000UNC_CBO_TWO_HYPH\000 */ 81 + { 683 }, /* unc_cbo_xsnp_response.miss_eviction\000uncore\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000event=0x22,umask=0x81\000\00000\000A cross-core snoop resulted from L3 Eviction which misses in some processor core\000 */ 82 + }; 83 + static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc[] = { 84 + { 1274 }, /* uncore_imc.cache_hits\000uncore\000Total cache hits\000event=0x34\000\00000\000Total cache hits\000 */ 85 + }; 86 + static const struct compact_pmu_event pmu_events__test_soc_cpu_uncore_imc_free_running[] = { 87 + { 1168 }, /* uncore_imc_free_running.cache_miss\000uncore\000Total cache misses\000event=0x12\000\00000\000Total cache misses\000 */ 88 + 89 + }; 90 + 91 + const struct pmu_table_entry pmu_events__test_soc_cpu[] = { 92 + { 93 + .entries = pmu_events__test_soc_cpu_default_core, 94 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_default_core), 95 + .pmu_name = { 0 /* default_core\000 */ }, 96 + }, 97 + { 98 + .entries = pmu_events__test_soc_cpu_hisi_sccl_ddrc, 99 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_ddrc), 100 + .pmu_name = { 570 /* hisi_sccl,ddrc\000 */ }, 101 + }, 102 + { 103 + .entries = pmu_events__test_soc_cpu_hisi_sccl_l3c, 104 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_hisi_sccl_l3c), 105 + .pmu_name = { 1050 /* hisi_sccl,l3c\000 */ }, 106 + }, 107 + { 108 + .entries = pmu_events__test_soc_cpu_uncore_cbox, 109 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_cbox), 110 + .pmu_name = { 671 /* uncore_cbox\000 */ }, 111 + }, 112 + { 113 + .entries = pmu_events__test_soc_cpu_uncore_imc, 114 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc), 115 + .pmu_name = { 1263 /* uncore_imc\000 */ }, 116 + }, 117 + { 118 + .entries = pmu_events__test_soc_cpu_uncore_imc_free_running, 119 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_cpu_uncore_imc_free_running), 120 + .pmu_name = { 1144 /* uncore_imc_free_running\000 */ }, 121 + }, 122 + }; 123 + 124 + static const struct compact_pmu_event pmu_metrics__test_soc_cpu_default_core[] = { 125 + { 1696 }, /* CPI\000\0001 / IPC\000\000\000\000\000\000\000\00000 */ 126 + { 2377 }, /* DCache_L2_All\000\000DCache_L2_All_Hits + DCache_L2_All_Miss\000\000\000\000\000\000\000\00000 */ 127 + { 2149 }, /* DCache_L2_All_Hits\000\000l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit\000\000\000\000\000\000\000\00000 */ 128 + { 2243 }, /* DCache_L2_All_Miss\000\000max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + l2_rqsts.pf_miss + l2_rqsts.rfo_miss\000\000\000\000\000\000\000\00000 */ 129 + { 2441 }, /* DCache_L2_Hits\000\000d_ratio(DCache_L2_All_Hits, DCache_L2_All)\000\000\000\000\000\000\000\00000 */ 130 + { 2509 }, /* DCache_L2_Misses\000\000d_ratio(DCache_L2_All_Miss, DCache_L2_All)\000\000\000\000\000\000\000\00000 */ 131 + { 1781 }, /* Frontend_Bound_SMT\000\000idq_uops_not_delivered.core / (4 * (cpu_clk_unhalted.thread / 2 * (1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk)))\000\000\000\000\000\000\000\00000 */ 132 + { 1718 }, /* IPC\000group1\000inst_retired.any / cpu_clk_unhalted.thread\000\000\000\000\000\000\000\00000 */ 133 + { 2643 }, /* L1D_Cache_Fill_BW\000\00064 * l1d.replacement / 1e9 / duration_time\000\000\000\000\000\000\000\00000 */ 134 + { 2579 }, /* M1\000\000ipc + M2\000\000\000\000\000\000\000\00000 */ 135 + { 2601 }, /* M2\000\000ipc + M1\000\000\000\000\000\000\000\00000 */ 136 + { 2623 }, /* M3\000\0001 / M3\000\000\000\000\000\000\000\00000 */ 137 + { 2078 }, /* cache_miss_cycles\000group1\000dcache_miss_cpi + icache_miss_cycles\000\000\000\000\000\000\000\00000 */ 138 + { 1947 }, /* dcache_miss_cpi\000\000l1d\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000 */ 139 + { 2011 }, /* icache_miss_cycles\000\000l1i\\-loads\\-misses / inst_retired.any\000\000\000\000\000\000\000\00000 */ 140 + 141 + }; 142 + 143 + const struct pmu_table_entry pmu_metrics__test_soc_cpu[] = { 144 + { 145 + .entries = pmu_metrics__test_soc_cpu_default_core, 146 + .num_entries = ARRAY_SIZE(pmu_metrics__test_soc_cpu_default_core), 147 + .pmu_name = { 0 /* default_core\000 */ }, 148 + }, 149 + }; 150 + 151 + static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_ccn_pmu[] = { 152 + { 1463 }, /* sys_ccn_pmu.read_cycles\000uncore\000ccn read-cycles event\000config=0x2c\0000x01\00000\000\000 */ 153 + }; 154 + static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_cmn_pmu[] = { 155 + { 1556 }, /* sys_cmn_pmu.hnf_cache_miss\000uncore\000Counts total cache misses in first lookup result (high priority)\000eventid=1,type=5\000(434|436|43c|43a).*\00000\000\000 */ 156 + }; 157 + static const struct compact_pmu_event pmu_events__test_soc_sys_uncore_sys_ddr_pmu[] = { 158 + { 1371 }, /* sys_ddr_pmu.write_cycles\000uncore\000ddr write-cycles event\000event=0x2b\000v8\00000\000\000 */ 159 + 160 + }; 161 + 162 + const struct pmu_table_entry pmu_events__test_soc_sys[] = { 163 + { 164 + .entries = pmu_events__test_soc_sys_uncore_sys_ccn_pmu, 165 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ccn_pmu), 166 + .pmu_name = { 1444 /* uncore_sys_ccn_pmu\000 */ }, 167 + }, 168 + { 169 + .entries = pmu_events__test_soc_sys_uncore_sys_cmn_pmu, 170 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_cmn_pmu), 171 + .pmu_name = { 1537 /* uncore_sys_cmn_pmu\000 */ }, 172 + }, 173 + { 174 + .entries = pmu_events__test_soc_sys_uncore_sys_ddr_pmu, 175 + .num_entries = ARRAY_SIZE(pmu_events__test_soc_sys_uncore_sys_ddr_pmu), 176 + .pmu_name = { 1352 /* uncore_sys_ddr_pmu\000 */ }, 177 + }, 178 + }; 179 + 185 180 186 181 /* Struct used to make the PMU event table implementation opaque to callers. */ 187 182 struct pmu_events_table { 188 - const struct pmu_event *entries; 183 + const struct pmu_table_entry *pmus; 184 + uint32_t num_pmus; 189 185 }; 190 186 191 187 /* Struct used to make the PMU metric table implementation opaque to callers. */ 192 188 struct pmu_metrics_table { 193 - const struct pmu_metric *entries; 189 + const struct pmu_table_entry *pmus; 190 + uint32_t num_pmus; 194 191 }; 195 192 196 193 /* ··· 199 202 * The cpuid can contain any character other than the comma. 200 203 */ 201 204 struct pmu_events_map { 202 - const char *arch; 203 - const char *cpuid; 204 - const struct pmu_events_table event_table; 205 - const struct pmu_metrics_table metric_table; 205 + const char *arch; 206 + const char *cpuid; 207 + struct pmu_events_table event_table; 208 + struct pmu_metrics_table metric_table; 206 209 }; 207 210 208 211 /* 209 212 * Global table mapping each known CPU for the architecture to its 210 213 * table of PMU events. 211 214 */ 212 - static const struct pmu_events_map pmu_events_map[] = { 213 - { 214 - .arch = "testarch", 215 - .cpuid = "testcpu", 216 - .event_table = { pmu_events__test_soc_cpu }, 217 - .metric_table = { pmu_metrics__test_soc_cpu }, 215 + const struct pmu_events_map pmu_events_map[] = { 216 + { 217 + .arch = "testarch", 218 + .cpuid = "testcpu", 219 + .event_table = { 220 + .pmus = pmu_events__test_soc_cpu, 221 + .num_pmus = ARRAY_SIZE(pmu_events__test_soc_cpu), 218 222 }, 219 - { 220 - .arch = 0, 221 - .cpuid = 0, 222 - .event_table = { 0 }, 223 - .metric_table = { 0 }, 224 - }, 225 - }; 226 - 227 - static const struct pmu_event pmu_events__test_soc_sys[] = { 228 - { 229 - .name = "sys_ddr_pmu.write_cycles", 230 - .event = "event=0x2b", 231 - .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", 232 - .compat = "v8", 233 - .topic = "uncore", 234 - .pmu = "uncore_sys_ddr_pmu", 235 - }, 236 - { 237 - .name = "sys_ccn_pmu.read_cycles", 238 - .event = "config=0x2c", 239 - .desc = "ccn read-cycles event. Unit: uncore_sys_ccn_pmu ", 240 - .compat = "0x01", 241 - .topic = "uncore", 242 - .pmu = "uncore_sys_ccn_pmu", 243 - }, 244 - { 245 - .name = "sys_cmn_pmu.hnf_cache_miss", 246 - .event = "eventid=0x1,type=0x5", 247 - .desc = "Counts total cache misses in first lookup result (high priority). Unit: uncore_sys_cmn_pmu ", 248 - .compat = "(434|436|43c|43a).*", 249 - .topic = "uncore", 250 - .pmu = "uncore_sys_cmn_pmu", 251 - }, 252 - { 253 - .name = 0, 254 - .event = 0, 255 - .desc = 0, 256 - }, 223 + .metric_table = { 224 + .pmus = pmu_metrics__test_soc_cpu, 225 + .num_pmus = ARRAY_SIZE(pmu_metrics__test_soc_cpu), 226 + } 227 + }, 228 + { 229 + .arch = 0, 230 + .cpuid = 0, 231 + .event_table = { 0, 0 }, 232 + .metric_table = { 0, 0 }, 233 + } 257 234 }; 258 235 259 236 struct pmu_sys_events { 260 237 const char *name; 261 - const struct pmu_events_table table; 238 + struct pmu_events_table event_table; 239 + struct pmu_metrics_table metric_table; 262 240 }; 263 241 264 242 static const struct pmu_sys_events pmu_sys_event_tables[] = { 265 243 { 266 - .table = { pmu_events__test_soc_sys }, 244 + .event_table = { 245 + .pmus = pmu_events__test_soc_sys, 246 + .num_pmus = ARRAY_SIZE(pmu_events__test_soc_sys) 247 + }, 267 248 .name = "pmu_events__test_soc_sys", 268 249 }, 269 250 { 270 - .table = { 0 } 251 + .event_table = { 0, 0 }, 252 + .metric_table = { 0, 0 }, 271 253 }, 272 254 }; 273 255 274 - int pmu_events_table__for_each_event(const struct pmu_events_table *table, struct perf_pmu *pmu, 275 - pmu_event_iter_fn fn, void *data) 256 + static void decompress_event(int offset, struct pmu_event *pe) 276 257 { 277 - for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { 278 - int ret; 258 + const char *p = &big_c_string[offset]; 279 259 280 - if (pmu && !pmu__name_match(pmu, pe->pmu)) 260 + pe->name = (*p == '\0' ? NULL : p); 261 + while (*p++); 262 + pe->topic = (*p == '\0' ? NULL : p); 263 + while (*p++); 264 + pe->desc = (*p == '\0' ? NULL : p); 265 + while (*p++); 266 + pe->event = (*p == '\0' ? NULL : p); 267 + while (*p++); 268 + pe->compat = (*p == '\0' ? NULL : p); 269 + while (*p++); 270 + pe->deprecated = *p - '0'; 271 + p++; 272 + pe->perpkg = *p - '0'; 273 + p++; 274 + pe->unit = (*p == '\0' ? NULL : p); 275 + while (*p++); 276 + pe->long_desc = (*p == '\0' ? NULL : p); 277 + } 278 + 279 + static void decompress_metric(int offset, struct pmu_metric *pm) 280 + { 281 + const char *p = &big_c_string[offset]; 282 + 283 + pm->metric_name = (*p == '\0' ? NULL : p); 284 + while (*p++); 285 + pm->metric_group = (*p == '\0' ? NULL : p); 286 + while (*p++); 287 + pm->metric_expr = (*p == '\0' ? NULL : p); 288 + while (*p++); 289 + pm->metric_threshold = (*p == '\0' ? NULL : p); 290 + while (*p++); 291 + pm->desc = (*p == '\0' ? NULL : p); 292 + while (*p++); 293 + pm->long_desc = (*p == '\0' ? NULL : p); 294 + while (*p++); 295 + pm->unit = (*p == '\0' ? NULL : p); 296 + while (*p++); 297 + pm->compat = (*p == '\0' ? NULL : p); 298 + while (*p++); 299 + pm->metricgroup_no_group = (*p == '\0' ? NULL : p); 300 + while (*p++); 301 + pm->default_metricgroup_name = (*p == '\0' ? NULL : p); 302 + while (*p++); 303 + pm->aggr_mode = *p - '0'; 304 + p++; 305 + pm->event_grouping = *p - '0'; 306 + } 307 + 308 + static int pmu_events_table__for_each_event_pmu(const struct pmu_events_table *table, 309 + const struct pmu_table_entry *pmu, 310 + pmu_event_iter_fn fn, 311 + void *data) 312 + { 313 + int ret; 314 + struct pmu_event pe = { 315 + .pmu = &big_c_string[pmu->pmu_name.offset], 316 + }; 317 + 318 + for (uint32_t i = 0; i < pmu->num_entries; i++) { 319 + decompress_event(pmu->entries[i].offset, &pe); 320 + if (!pe.name) 321 + continue; 322 + ret = fn(&pe, table, data); 323 + if (ret) 324 + return ret; 325 + } 326 + return 0; 327 + } 328 + 329 + static int pmu_events_table__find_event_pmu(const struct pmu_events_table *table, 330 + const struct pmu_table_entry *pmu, 331 + const char *name, 332 + pmu_event_iter_fn fn, 333 + void *data) 334 + { 335 + struct pmu_event pe = { 336 + .pmu = &big_c_string[pmu->pmu_name.offset], 337 + }; 338 + int low = 0, high = pmu->num_entries - 1; 339 + 340 + while (low <= high) { 341 + int cmp, mid = (low + high) / 2; 342 + 343 + decompress_event(pmu->entries[mid].offset, &pe); 344 + 345 + if (!pe.name && !name) 346 + goto do_call; 347 + 348 + if (!pe.name && name) { 349 + low = mid + 1; 350 + continue; 351 + } 352 + if (pe.name && !name) { 353 + high = mid - 1; 354 + continue; 355 + } 356 + 357 + cmp = strcasecmp(pe.name, name); 358 + if (cmp < 0) { 359 + low = mid + 1; 360 + continue; 361 + } 362 + if (cmp > 0) { 363 + high = mid - 1; 364 + continue; 365 + } 366 + do_call: 367 + return fn ? fn(&pe, table, data) : 0; 368 + } 369 + return PMU_EVENTS__NOT_FOUND; 370 + } 371 + 372 + int pmu_events_table__for_each_event(const struct pmu_events_table *table, 373 + struct perf_pmu *pmu, 374 + pmu_event_iter_fn fn, 375 + void *data) 376 + { 377 + for (size_t i = 0; i < table->num_pmus; i++) { 378 + const struct pmu_table_entry *table_pmu = &table->pmus[i]; 379 + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; 380 + int ret; 381 + 382 + if (pmu && !pmu__name_match(pmu, pmu_name)) 281 383 continue; 282 384 283 - ret = fn(pe, table, data); 284 - if (ret) 285 - return ret; 286 - } 287 - return 0; 385 + ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data); 386 + if (pmu || ret) 387 + return ret; 388 + } 389 + return 0; 288 390 } 289 391 290 392 int pmu_events_table__find_event(const struct pmu_events_table *table, ··· 392 296 pmu_event_iter_fn fn, 393 297 void *data) 394 298 { 395 - for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { 396 - if (pmu && !pmu__name_match(pmu, pe->pmu)) 299 + for (size_t i = 0; i < table->num_pmus; i++) { 300 + const struct pmu_table_entry *table_pmu = &table->pmus[i]; 301 + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; 302 + int ret; 303 + 304 + if (!pmu__name_match(pmu, pmu_name)) 397 305 continue; 398 306 399 - if (!strcasecmp(pe->name, name)) 400 - return fn(pe, table, data); 401 - } 402 - return -1000; 307 + ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data); 308 + if (ret != PMU_EVENTS__NOT_FOUND) 309 + return ret; 310 + } 311 + return PMU_EVENTS__NOT_FOUND; 403 312 } 404 313 405 314 size_t pmu_events_table__num_events(const struct pmu_events_table *table, ··· 412 311 { 413 312 size_t count = 0; 414 313 415 - for (const struct pmu_event *pe = &table->entries[0]; pe->name; pe++) { 416 - if (pmu && !pmu__name_match(pmu, pe->pmu)) 417 - continue; 314 + for (size_t i = 0; i < table->num_pmus; i++) { 315 + const struct pmu_table_entry *table_pmu = &table->pmus[i]; 316 + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; 418 317 419 - count++; 420 - } 318 + if (pmu__name_match(pmu, pmu_name)) 319 + count += table_pmu->num_entries; 320 + } 421 321 return count; 422 322 } 423 323 424 - int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn, 425 - void *data) 324 + static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics_table *table, 325 + const struct pmu_table_entry *pmu, 326 + pmu_metric_iter_fn fn, 327 + void *data) 426 328 { 427 - for (const struct pmu_metric *pm = &table->entries[0]; pm->metric_expr; pm++) { 428 - int ret = fn(pm, table, data); 329 + int ret; 330 + struct pmu_metric pm = { 331 + .pmu = &big_c_string[pmu->pmu_name.offset], 332 + }; 429 333 430 - if (ret) 431 - return ret; 432 - } 433 - return 0; 334 + for (uint32_t i = 0; i < pmu->num_entries; i++) { 335 + decompress_metric(pmu->entries[i].offset, &pm); 336 + if (!pm.metric_expr) 337 + continue; 338 + ret = fn(&pm, table, data); 339 + if (ret) 340 + return ret; 341 + } 342 + return 0; 343 + } 344 + 345 + int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, 346 + pmu_metric_iter_fn fn, 347 + void *data) 348 + { 349 + for (size_t i = 0; i < table->num_pmus; i++) { 350 + int ret = pmu_metrics_table__for_each_metric_pmu(table, &table->pmus[i], 351 + fn, data); 352 + 353 + if (ret) 354 + return ret; 355 + } 356 + return 0; 357 + } 358 + 359 + static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu) 360 + { 361 + static struct { 362 + const struct pmu_events_map *map; 363 + struct perf_pmu *pmu; 364 + } last_result; 365 + static struct { 366 + const struct pmu_events_map *map; 367 + char *cpuid; 368 + } last_map_search; 369 + static bool has_last_result, has_last_map_search; 370 + const struct pmu_events_map *map = NULL; 371 + char *cpuid = NULL; 372 + size_t i; 373 + 374 + if (has_last_result && last_result.pmu == pmu) 375 + return last_result.map; 376 + 377 + cpuid = perf_pmu__getcpuid(pmu); 378 + 379 + /* 380 + * On some platforms which uses cpus map, cpuid can be NULL for 381 + * PMUs other than CORE PMUs. 382 + */ 383 + if (!cpuid) 384 + goto out_update_last_result; 385 + 386 + if (has_last_map_search && !strcmp(last_map_search.cpuid, cpuid)) { 387 + map = last_map_search.map; 388 + free(cpuid); 389 + } else { 390 + i = 0; 391 + for (;;) { 392 + map = &pmu_events_map[i++]; 393 + 394 + if (!map->arch) { 395 + map = NULL; 396 + break; 397 + } 398 + 399 + if (!strcmp_cpuid_str(map->cpuid, cpuid)) 400 + break; 401 + } 402 + free(last_map_search.cpuid); 403 + last_map_search.cpuid = cpuid; 404 + last_map_search.map = map; 405 + has_last_map_search = true; 406 + } 407 + out_update_last_result: 408 + last_result.pmu = pmu; 409 + last_result.map = map; 410 + has_last_result = true; 411 + return map; 434 412 } 435 413 436 414 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu) 437 415 { 438 - const struct pmu_events_table *table = NULL; 439 - char *cpuid = perf_pmu__getcpuid(pmu); 440 - int i; 416 + const struct pmu_events_map *map = map_for_pmu(pmu); 441 417 442 - /* on some platforms which uses cpus map, cpuid can be NULL for 443 - * PMUs other than CORE PMUs. 444 - */ 445 - if (!cpuid) 446 - return NULL; 418 + if (!map) 419 + return NULL; 447 420 448 - i = 0; 449 - for (;;) { 450 - const struct pmu_events_map *map = &pmu_events_map[i++]; 421 + if (!pmu) 422 + return &map->event_table; 451 423 452 - if (!map->cpuid) 453 - break; 424 + for (size_t i = 0; i < map->event_table.num_pmus; i++) { 425 + const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i]; 426 + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; 454 427 455 - if (!strcmp_cpuid_str(map->cpuid, cpuid)) { 456 - table = &map->event_table; 457 - break; 458 - } 459 - } 460 - free(cpuid); 461 - return table; 428 + if (pmu__name_match(pmu, pmu_name)) 429 + return &map->event_table; 430 + } 431 + return NULL; 462 432 } 463 433 464 434 const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu) 465 435 { 466 - const struct pmu_metrics_table *table = NULL; 467 - char *cpuid = perf_pmu__getcpuid(pmu); 468 - int i; 436 + const struct pmu_events_map *map = map_for_pmu(pmu); 469 437 470 - /* on some platforms which uses cpus map, cpuid can be NULL for 471 - * PMUs other than CORE PMUs. 472 - */ 473 - if (!cpuid) 474 - return NULL; 438 + if (!map) 439 + return NULL; 475 440 476 - i = 0; 477 - for (;;) { 478 - const struct pmu_events_map *map = &pmu_events_map[i++]; 441 + if (!pmu) 442 + return &map->metric_table; 479 443 480 - if (!map->cpuid) 481 - break; 444 + for (size_t i = 0; i < map->metric_table.num_pmus; i++) { 445 + const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i]; 446 + const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset]; 482 447 483 - if (!strcmp_cpuid_str(map->cpuid, cpuid)) { 484 - table = &map->metric_table; 485 - break; 486 - } 487 - } 488 - free(cpuid); 489 - return table; 448 + if (pmu__name_match(pmu, pmu_name)) 449 + return &map->metric_table; 450 + } 451 + return NULL; 490 452 } 491 453 492 454 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid) 493 455 { 494 - for (const struct pmu_events_map *tables = &pmu_events_map[0]; 495 - tables->arch; 496 - tables++) { 497 - if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 498 - return &tables->event_table; 499 - } 500 - return NULL; 456 + for (const struct pmu_events_map *tables = &pmu_events_map[0]; 457 + tables->arch; 458 + tables++) { 459 + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 460 + return &tables->event_table; 461 + } 462 + return NULL; 501 463 } 502 464 503 465 const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid) 504 466 { 505 - for (const struct pmu_events_map *tables = &pmu_events_map[0]; 506 - tables->arch; 507 - tables++) { 508 - if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 509 - return &tables->metric_table; 510 - } 511 - return NULL; 467 + for (const struct pmu_events_map *tables = &pmu_events_map[0]; 468 + tables->arch; 469 + tables++) { 470 + if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid)) 471 + return &tables->metric_table; 472 + } 473 + return NULL; 512 474 } 513 475 514 476 int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data) 515 477 { 516 - for (const struct pmu_events_map *tables = &pmu_events_map[0]; tables->arch; tables++) { 517 - int ret = pmu_events_table__for_each_event(&tables->event_table, 518 - /*pmu=*/ NULL, fn, data); 478 + for (const struct pmu_events_map *tables = &pmu_events_map[0]; 479 + tables->arch; 480 + tables++) { 481 + int ret = pmu_events_table__for_each_event(&tables->event_table, 482 + /*pmu=*/ NULL, fn, data); 519 483 520 - if (ret) 521 - return ret; 522 - } 523 - return 0; 484 + if (ret) 485 + return ret; 486 + } 487 + return 0; 524 488 } 525 489 526 490 int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data) 527 491 { 528 - for (const struct pmu_events_map *tables = &pmu_events_map[0]; 529 - tables->arch; 530 - tables++) { 531 - int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); 492 + for (const struct pmu_events_map *tables = &pmu_events_map[0]; 493 + tables->arch; 494 + tables++) { 495 + int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); 532 496 533 - if (ret) 534 - return ret; 535 - } 536 - return 0; 497 + if (ret) 498 + return ret; 499 + } 500 + return 0; 537 501 } 538 502 539 503 const struct pmu_events_table *find_sys_events_table(const char *name) 540 504 { 541 - for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 542 - tables->name; 543 - tables++) { 544 - if (!strcmp(tables->name, name)) 545 - return &tables->table; 546 - } 547 - return NULL; 505 + for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 506 + tables->name; 507 + tables++) { 508 + if (!strcmp(tables->name, name)) 509 + return &tables->event_table; 510 + } 511 + return NULL; 548 512 } 549 513 550 514 int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data) 551 515 { 552 - for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 553 - tables->name; 554 - tables++) { 555 - int ret = pmu_events_table__for_each_event(&tables->table, /*pmu=*/ NULL, fn, data); 516 + for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 517 + tables->name; 518 + tables++) { 519 + int ret = pmu_events_table__for_each_event(&tables->event_table, 520 + /*pmu=*/ NULL, fn, data); 556 521 557 - if (ret) 558 - return ret; 559 - } 560 - return 0; 522 + if (ret) 523 + return ret; 524 + } 525 + return 0; 561 526 } 562 527 563 - int pmu_for_each_sys_metric(pmu_metric_iter_fn fn __maybe_unused, void *data __maybe_unused) 528 + int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data) 564 529 { 565 - return 0; 530 + for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; 531 + tables->name; 532 + tables++) { 533 + int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data); 534 + 535 + if (ret) 536 + return ret; 537 + } 538 + return 0; 566 539 } 567 540 568 - const char *describe_metricgroup(const char *group __maybe_unused) 541 + static const int metricgroups[][2] = { 542 + 543 + }; 544 + 545 + const char *describe_metricgroup(const char *group) 569 546 { 570 - return NULL; 547 + int low = 0, high = (int)ARRAY_SIZE(metricgroups) - 1; 548 + 549 + while (low <= high) { 550 + int mid = (low + high) / 2; 551 + const char *mgroup = &big_c_string[metricgroups[mid][0]]; 552 + int cmp = strcmp(mgroup, group); 553 + 554 + if (cmp == 0) { 555 + return &big_c_string[metricgroups[mid][1]]; 556 + } else if (cmp < 0) { 557 + low = mid + 1; 558 + } else { 559 + high = mid - 1; 560 + } 561 + } 562 + return NULL; 571 563 }
+5 -1
tools/perf/pmu-events/jevents.py
··· 1256 1256 'output_file', type=argparse.FileType('w', encoding='utf-8'), nargs='?', default=sys.stdout) 1257 1257 _args = ap.parse_args() 1258 1258 1259 + _args.output_file.write(f""" 1260 + /* SPDX-License-Identifier: GPL-2.0 */ 1261 + /* THIS FILE WAS AUTOGENERATED BY jevents.py arch={_args.arch} model={_args.model} ! */ 1262 + """) 1259 1263 _args.output_file.write(""" 1260 1264 #include <pmu-events/pmu-events.h> 1261 1265 #include "util/header.h" ··· 1285 1281 if item.name == _args.arch or _args.arch == 'all' or item.name == 'test': 1286 1282 archs.append(item.name) 1287 1283 1288 - if len(archs) < 2: 1284 + if len(archs) < 2 and _args.arch != 'none': 1289 1285 raise IOError(f'Missing architecture directory \'{_args.arch}\'') 1290 1286 1291 1287 archs.sort()