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

perf mem: Clean up perf_mem_events__name()

Introduce a generic perf_mem_events__name(). Remove the ARCH-specific
one.

The mem_load events may have a different format. Add ldlat and aux_event
in the struct perf_mem_event to indicate the format and the extra aux
event.

Add perf_mem_events_intel_aux[] to support the extra mem_load_aux event.

Rename perf_mem_events__name to perf_pmu__mem_events_name.

Reviewed-by: Ian Rogers <irogers@google.com>
Tested-by: Ravi Bangoria <ravi.bangoria@amd.com>
Tested-by: Leo Yan <leo.yan@linaro.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Cc: james.clark@arm.com
Cc: will@kernel.org
Cc: mike.leach@linaro.org
Cc: renyu.zj@linux.alibaba.com
Cc: yuhaixin.yhx@linux.alibaba.com
Cc: tmricht@linux.ibm.com
Cc: atrajeev@linux.vnet.ibm.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: john.g.garry@oracle.com
Link: https://lore.kernel.org/r/20240123185036.3461837-4-kan.liang@linux.intel.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Kan Liang and committed by
Namhyung Kim
abbdd79b a30450e6

+97 -107
+4 -22
tools/perf/arch/arm64/util/mem-events.c
··· 3 3 #include "util/mem-events.h" 4 4 #include "mem-events.h" 5 5 6 - #define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s } 6 + #define E(t, n, s, l, a) { .tag = t, .name = n, .sysfs_name = s, .ldlat = l, .aux_event = a } 7 7 8 8 struct perf_mem_event perf_mem_events_arm[PERF_MEM_EVENTS__MAX] = { 9 - E("spe-load", "arm_spe_0/ts_enable=1,pa_enable=1,load_filter=1,store_filter=0,min_latency=%u/", "arm_spe_0"), 10 - E("spe-store", "arm_spe_0/ts_enable=1,pa_enable=1,load_filter=0,store_filter=1/", "arm_spe_0"), 11 - E("spe-ldst", "arm_spe_0/ts_enable=1,pa_enable=1,load_filter=1,store_filter=1,min_latency=%u/", "arm_spe_0"), 9 + E("spe-load", "%s/ts_enable=1,pa_enable=1,load_filter=1,store_filter=0,min_latency=%u/", "arm_spe_0", true, 0), 10 + E("spe-store", "%s/ts_enable=1,pa_enable=1,load_filter=0,store_filter=1/", "arm_spe_0", false, 0), 11 + E("spe-ldst", "%s/ts_enable=1,pa_enable=1,load_filter=1,store_filter=1,min_latency=%u/", "arm_spe_0", true, 0), 12 12 }; 13 - 14 - static char mem_ev_name[100]; 15 - 16 - const char *perf_mem_events__name(int i, const char *pmu_name __maybe_unused) 17 - { 18 - struct perf_mem_event *e = &perf_mem_events_arm[i]; 19 - 20 - if (i >= PERF_MEM_EVENTS__MAX) 21 - return NULL; 22 - 23 - if (i == PERF_MEM_EVENTS__LOAD || i == PERF_MEM_EVENTS__LOAD_STORE) 24 - scnprintf(mem_ev_name, sizeof(mem_ev_name), 25 - e->name, perf_mem_events__loads_ldlat); 26 - else /* PERF_MEM_EVENTS__STORE */ 27 - scnprintf(mem_ev_name, sizeof(mem_ev_name), e->name); 28 - 29 - return mem_ev_name; 30 - }
+1
tools/perf/arch/powerpc/util/Build
··· 2 2 perf-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o 3 3 perf-y += perf_regs.o 4 4 perf-y += mem-events.o 5 + perf-y += pmu.o 5 6 perf-y += sym-handling.o 6 7 perf-y += evsel.o 7 8 perf-y += event.o
+8 -8
tools/perf/arch/powerpc/util/mem-events.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - #include "map_symbol.h" 2 + #include "util/map_symbol.h" 3 + #include "util/mem-events.h" 3 4 #include "mem-events.h" 4 5 5 - /* PowerPC does not support 'ldlat' parameter. */ 6 - const char *perf_mem_events__name(int i, const char *pmu_name __maybe_unused) 7 - { 8 - if (i == PERF_MEM_EVENTS__LOAD) 9 - return "cpu/mem-loads/"; 6 + #define E(t, n, s, l, a) { .tag = t, .name = n, .sysfs_name = s, .ldlat = l, .aux_event = a } 10 7 11 - return "cpu/mem-stores/"; 12 - } 8 + struct perf_mem_event perf_mem_events_power[PERF_MEM_EVENTS__MAX] = { 9 + E("ldlat-loads", "%s/mem-loads/", "cpu/events/mem-loads", false, 0), 10 + E("ldlat-stores", "%s/mem-stores/", "cpu/events/mem-stores", false, 0), 11 + E(NULL, NULL, NULL, false, 0), 12 + };
+7
tools/perf/arch/powerpc/util/mem-events.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _POWER_MEM_EVENTS_H 3 + #define _POWER_MEM_EVENTS_H 4 + 5 + extern struct perf_mem_event perf_mem_events_power[PERF_MEM_EVENTS__MAX]; 6 + 7 + #endif /* _POWER_MEM_EVENTS_H */
+12
tools/perf/arch/powerpc/util/pmu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <string.h> 4 + 5 + #include "../../../util/pmu.h" 6 + #include "mem-events.h" 7 + 8 + void perf_pmu__arch_init(struct perf_pmu *pmu) 9 + { 10 + if (pmu->is_core) 11 + pmu->mem_events = perf_mem_events_power; 12 + }
+13 -57
tools/perf/arch/x86/util/mem-events.c
··· 7 7 #include "linux/string.h" 8 8 #include "env.h" 9 9 10 - static char mem_loads_name[100]; 11 - static bool mem_loads_name__init; 12 - static char mem_stores_name[100]; 13 - 14 10 #define MEM_LOADS_AUX 0x8203 15 - #define MEM_LOADS_AUX_NAME "{%s/mem-loads-aux/,%s/mem-loads,ldlat=%u/}:P" 16 11 17 - #define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s } 12 + #define E(t, n, s, l, a) { .tag = t, .name = n, .sysfs_name = s, .ldlat = l, .aux_event = a } 18 13 19 14 struct perf_mem_event perf_mem_events_intel[PERF_MEM_EVENTS__MAX] = { 20 - E("ldlat-loads", "%s/mem-loads,ldlat=%u/P", "%s/events/mem-loads"), 21 - E("ldlat-stores", "%s/mem-stores/P", "%s/events/mem-stores"), 22 - E(NULL, NULL, NULL), 15 + E("ldlat-loads", "%s/mem-loads,ldlat=%u/P", "%s/events/mem-loads", true, 0), 16 + E("ldlat-stores", "%s/mem-stores/P", "%s/events/mem-stores", false, 0), 17 + E(NULL, NULL, NULL, false, 0), 18 + }; 19 + 20 + struct perf_mem_event perf_mem_events_intel_aux[PERF_MEM_EVENTS__MAX] = { 21 + E("ldlat-loads", "{%s/mem-loads-aux/,%s/mem-loads,ldlat=%u/}:P", "%s/events/mem-loads", true, MEM_LOADS_AUX), 22 + E("ldlat-stores", "%s/mem-stores/P", "%s/events/mem-stores", false, 0), 23 + E(NULL, NULL, NULL, false, 0), 23 24 }; 24 25 25 26 struct perf_mem_event perf_mem_events_amd[PERF_MEM_EVENTS__MAX] = { 26 - E(NULL, NULL, NULL), 27 - E(NULL, NULL, NULL), 28 - E("mem-ldst", "ibs_op//", "ibs_op"), 27 + E(NULL, NULL, NULL, false, 0), 28 + E(NULL, NULL, NULL, false, 0), 29 + E("mem-ldst", "%s//", "ibs_op", false, 0), 29 30 }; 30 31 31 32 bool is_mem_loads_aux_event(struct evsel *leader) ··· 40 39 return false; 41 40 42 41 return leader->core.attr.config == MEM_LOADS_AUX; 43 - } 44 - 45 - const char *perf_mem_events__name(int i, const char *pmu_name) 46 - { 47 - struct perf_mem_event *e; 48 - 49 - if (x86__is_amd_cpu()) 50 - e = &perf_mem_events_amd[i]; 51 - else 52 - e = &perf_mem_events_intel[i]; 53 - 54 - if (!e) 55 - return NULL; 56 - 57 - if (i == PERF_MEM_EVENTS__LOAD) { 58 - if (mem_loads_name__init && !pmu_name) 59 - return mem_loads_name; 60 - 61 - if (!pmu_name) { 62 - mem_loads_name__init = true; 63 - pmu_name = "cpu"; 64 - } 65 - 66 - if (perf_pmus__have_event(pmu_name, "mem-loads-aux")) { 67 - scnprintf(mem_loads_name, sizeof(mem_loads_name), 68 - MEM_LOADS_AUX_NAME, pmu_name, pmu_name, 69 - perf_mem_events__loads_ldlat); 70 - } else { 71 - scnprintf(mem_loads_name, sizeof(mem_loads_name), 72 - e->name, pmu_name, 73 - perf_mem_events__loads_ldlat); 74 - } 75 - return mem_loads_name; 76 - } 77 - 78 - if (i == PERF_MEM_EVENTS__STORE) { 79 - if (!pmu_name) 80 - pmu_name = "cpu"; 81 - 82 - scnprintf(mem_stores_name, sizeof(mem_stores_name), 83 - e->name, pmu_name); 84 - return mem_stores_name; 85 - } 86 - 87 - return e->name; 88 42 }
+1
tools/perf/arch/x86/util/mem-events.h
··· 3 3 #define _X86_MEM_EVENTS_H 4 4 5 5 extern struct perf_mem_event perf_mem_events_intel[PERF_MEM_EVENTS__MAX]; 6 + extern struct perf_mem_event perf_mem_events_intel_aux[PERF_MEM_EVENTS__MAX]; 6 7 7 8 extern struct perf_mem_event perf_mem_events_amd[PERF_MEM_EVENTS__MAX]; 8 9
+6 -2
tools/perf/arch/x86/util/pmu.c
··· 35 35 if (x86__is_amd_cpu()) { 36 36 if (!strcmp(pmu->name, "ibs_op")) 37 37 pmu->mem_events = perf_mem_events_amd; 38 - } else if (pmu->is_core) 39 - pmu->mem_events = perf_mem_events_intel; 38 + } else if (pmu->is_core) { 39 + if (perf_pmu__have_event(pmu, "mem-loads-aux")) 40 + pmu->mem_events = perf_mem_events_intel_aux; 41 + else 42 + pmu->mem_events = perf_mem_events_intel; 43 + } 40 44 } 41 45 42 46 int perf_pmus__num_mem_pmus(void)
+43 -17
tools/perf/util/mem-events.c
··· 17 17 18 18 unsigned int perf_mem_events__loads_ldlat = 30; 19 19 20 - #define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s } 20 + #define E(t, n, s, l, a) { .tag = t, .name = n, .sysfs_name = s, .ldlat = l, .aux_event = a } 21 21 22 22 struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = { 23 - E("ldlat-loads", "cpu/mem-loads,ldlat=%u/P", "cpu/events/mem-loads"), 24 - E("ldlat-stores", "cpu/mem-stores/P", "cpu/events/mem-stores"), 25 - E(NULL, NULL, NULL), 23 + E("ldlat-loads", "%s/mem-loads,ldlat=%u/P", "cpu/events/mem-loads", true, 0), 24 + E("ldlat-stores", "%s/mem-stores/P", "cpu/events/mem-stores", false, 0), 25 + E(NULL, NULL, NULL, false, 0), 26 26 }; 27 27 #undef E 28 28 29 29 static char mem_loads_name[100]; 30 - static bool mem_loads_name__init; 30 + static char mem_stores_name[100]; 31 31 32 32 struct perf_mem_event *perf_pmu__mem_events_ptr(struct perf_pmu *pmu, int i) 33 33 { ··· 62 62 return perf_pmus__scan_mem(NULL); 63 63 } 64 64 65 - const char * __weak perf_mem_events__name(int i, const char *pmu_name __maybe_unused) 65 + static const char *perf_pmu__mem_events_name(int i, struct perf_pmu *pmu) 66 66 { 67 - struct perf_mem_event *e = &perf_mem_events[i]; 67 + struct perf_mem_event *e; 68 68 69 + if (i >= PERF_MEM_EVENTS__MAX || !pmu) 70 + return NULL; 71 + 72 + e = &pmu->mem_events[i]; 69 73 if (!e) 70 74 return NULL; 71 75 72 - if (i == PERF_MEM_EVENTS__LOAD) { 73 - if (!mem_loads_name__init) { 74 - mem_loads_name__init = true; 75 - scnprintf(mem_loads_name, sizeof(mem_loads_name), 76 - e->name, perf_mem_events__loads_ldlat); 76 + if (i == PERF_MEM_EVENTS__LOAD || i == PERF_MEM_EVENTS__LOAD_STORE) { 77 + if (e->ldlat) { 78 + if (!e->aux_event) { 79 + /* ARM and Most of Intel */ 80 + scnprintf(mem_loads_name, sizeof(mem_loads_name), 81 + e->name, pmu->name, 82 + perf_mem_events__loads_ldlat); 83 + } else { 84 + /* Intel with mem-loads-aux event */ 85 + scnprintf(mem_loads_name, sizeof(mem_loads_name), 86 + e->name, pmu->name, pmu->name, 87 + perf_mem_events__loads_ldlat); 88 + } 89 + } else { 90 + if (!e->aux_event) { 91 + /* AMD and POWER */ 92 + scnprintf(mem_loads_name, sizeof(mem_loads_name), 93 + e->name, pmu->name); 94 + } else 95 + return NULL; 77 96 } 97 + 78 98 return mem_loads_name; 79 99 } 80 100 81 - return e->name; 101 + if (i == PERF_MEM_EVENTS__STORE) { 102 + scnprintf(mem_stores_name, sizeof(mem_stores_name), 103 + e->name, pmu->name); 104 + return mem_stores_name; 105 + } 106 + 107 + return NULL; 82 108 } 83 109 84 110 __weak bool is_mem_loads_aux_event(struct evsel *leader __maybe_unused) ··· 201 175 e->tag ? 13 : 0, 202 176 e->tag ? : "", 203 177 e->tag && verbose > 0 ? 25 : 0, 204 - e->tag && verbose > 0 ? perf_mem_events__name(j, NULL) : "", 178 + e->tag && verbose > 0 ? perf_pmu__mem_events_name(j, pmu) : "", 205 179 e->supported ? ": available\n" : ""); 206 180 } 207 181 } ··· 224 198 225 199 if (!e->supported) { 226 200 pr_err("failed: event '%s' not supported\n", 227 - perf_mem_events__name(j, pmu->name)); 201 + perf_pmu__mem_events_name(j, pmu)); 228 202 return -1; 229 203 } 230 204 231 205 if (perf_pmus__num_mem_pmus() == 1) { 232 206 rec_argv[i++] = "-e"; 233 - rec_argv[i++] = perf_mem_events__name(j, NULL); 207 + rec_argv[i++] = perf_pmu__mem_events_name(j, pmu); 234 208 } else { 235 - const char *s = perf_mem_events__name(j, pmu->name); 209 + const char *s = perf_pmu__mem_events_name(j, pmu); 236 210 237 211 if (!perf_mem_event__supported(mnt, pmu, e)) 238 212 continue;
+2 -1
tools/perf/util/mem-events.h
··· 14 14 struct perf_mem_event { 15 15 bool record; 16 16 bool supported; 17 + bool ldlat; 18 + u32 aux_event; 17 19 const char *tag; 18 20 const char *name; 19 21 const char *sysfs_name; ··· 41 39 int perf_pmu__mem_events_parse(struct perf_pmu *pmu, const char *str); 42 40 int perf_pmu__mem_events_init(struct perf_pmu *pmu); 43 41 44 - const char *perf_mem_events__name(int i, const char *pmu_name); 45 42 struct perf_mem_event *perf_pmu__mem_events_ptr(struct perf_pmu *pmu, int i); 46 43 struct perf_pmu *perf_mem_events_find_pmu(void); 47 44 bool is_mem_loads_aux_event(struct evsel *leader);