Skip to content

Commit d9c5f5f

Browse files
captain5050acmel
authored andcommitted
perf pmu: Count sys and cpuid JSON events separately
Sys events are eagerly loaded as each event has a compat option that may mean the event is or isn't associated with the PMU. These shouldn't be counted as loaded_json_events as that is used for JSON events matching the CPUID that may or may not have been loaded. The mismatch causes issues on ARM64 that uses sys events. Fixes: e6ff1ee ("perf pmu: Lazily add JSON events") Closes: https://lore.kernel.org/lkml/[email protected]/ Reported-by: Jia He <[email protected]> Signed-off-by: Ian Rogers <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: John Garry <[email protected]> Cc: Kan Liang <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 193a9e3 commit d9c5f5f

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

tools/perf/util/pmu.c

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ struct perf_pmu perf_pmu__fake = {
3636

3737
#define UNIT_MAX_LEN 31 /* max length for event unit name */
3838

39+
enum event_source {
40+
/* An event loaded from /sys/devices/<pmu>/events. */
41+
EVENT_SRC_SYSFS,
42+
/* An event loaded from a CPUID matched json file. */
43+
EVENT_SRC_CPU_JSON,
44+
/*
45+
* An event loaded from a /sys/devices/<pmu>/identifier matched json
46+
* file.
47+
*/
48+
EVENT_SRC_SYS_JSON,
49+
};
50+
3951
/**
4052
* struct perf_pmu_alias - An event either read from sysfs or builtin in
4153
* pmu-events.c, created by parsing the pmu-events json files.
@@ -521,7 +533,7 @@ static int update_alias(const struct pmu_event *pe,
521533

522534
static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
523535
const char *desc, const char *val, FILE *val_fd,
524-
const struct pmu_event *pe)
536+
const struct pmu_event *pe, enum event_source src)
525537
{
526538
struct perf_pmu_alias *alias;
527539
int ret;
@@ -574,25 +586,30 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name,
574586
}
575587
snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
576588
}
577-
if (!pe) {
578-
/* Update an event from sysfs with json data. */
579-
struct update_alias_data data = {
580-
.pmu = pmu,
581-
.alias = alias,
582-
};
583-
589+
switch (src) {
590+
default:
591+
case EVENT_SRC_SYSFS:
584592
alias->from_sysfs = true;
585593
if (pmu->events_table) {
594+
/* Update an event from sysfs with json data. */
595+
struct update_alias_data data = {
596+
.pmu = pmu,
597+
.alias = alias,
598+
};
586599
if (pmu_events_table__find_event(pmu->events_table, pmu, name,
587600
update_alias, &data) == 0)
588-
pmu->loaded_json_aliases++;
601+
pmu->cpu_json_aliases++;
589602
}
590-
}
591-
592-
if (!pe)
593603
pmu->sysfs_aliases++;
594-
else
595-
pmu->loaded_json_aliases++;
604+
break;
605+
case EVENT_SRC_CPU_JSON:
606+
pmu->cpu_json_aliases++;
607+
break;
608+
case EVENT_SRC_SYS_JSON:
609+
pmu->sys_json_aliases++;
610+
break;
611+
612+
}
596613
list_add_tail(&alias->list, &pmu->aliases);
597614
return 0;
598615
}
@@ -653,7 +670,8 @@ static int __pmu_aliases_parse(struct perf_pmu *pmu, int events_dir_fd)
653670
}
654671

655672
if (perf_pmu__new_alias(pmu, name, /*desc=*/ NULL,
656-
/*val=*/ NULL, file, /*pe=*/ NULL) < 0)
673+
/*val=*/ NULL, file, /*pe=*/ NULL,
674+
EVENT_SRC_SYSFS) < 0)
657675
pr_debug("Cannot set up %s\n", name);
658676
fclose(file);
659677
}
@@ -946,7 +964,8 @@ static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe,
946964
{
947965
struct perf_pmu *pmu = vdata;
948966

949-
perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=*/ NULL, pe);
967+
perf_pmu__new_alias(pmu, pe->name, pe->desc, pe->event, /*val_fd=*/ NULL,
968+
pe, EVENT_SRC_CPU_JSON);
950969
return 0;
951970
}
952971

@@ -981,13 +1000,14 @@ static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe,
9811000
return 0;
9821001

9831002
if (pmu_uncore_alias_match(pe->pmu, pmu->name) &&
984-
pmu_uncore_identifier_match(pe->compat, pmu->id)) {
1003+
pmu_uncore_identifier_match(pe->compat, pmu->id)) {
9851004
perf_pmu__new_alias(pmu,
9861005
pe->name,
9871006
pe->desc,
9881007
pe->event,
9891008
/*val_fd=*/ NULL,
990-
pe);
1009+
pe,
1010+
EVENT_SRC_SYS_JSON);
9911011
}
9921012

9931013
return 0;
@@ -1082,6 +1102,12 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char
10821102
pmu->max_precise = pmu_max_precise(dirfd, pmu);
10831103
pmu->alias_name = pmu_find_alias_name(pmu, dirfd);
10841104
pmu->events_table = perf_pmu__find_events_table(pmu);
1105+
/*
1106+
* Load the sys json events/aliases when loading the PMU as each event
1107+
* may have a different compat regular expression. We therefore can't
1108+
* know the number of sys json events/aliases without computing the
1109+
* regular expressions for them all.
1110+
*/
10851111
pmu_add_sys_aliases(pmu);
10861112
list_add_tail(&pmu->list, pmus);
10871113

@@ -1739,12 +1765,14 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
17391765
size_t nr;
17401766

17411767
pmu_aliases_parse(pmu);
1742-
nr = pmu->sysfs_aliases;
1768+
nr = pmu->sysfs_aliases + pmu->sys_json_aliases;;
17431769

17441770
if (pmu->cpu_aliases_added)
1745-
nr += pmu->loaded_json_aliases;
1771+
nr += pmu->cpu_json_aliases;
17461772
else if (pmu->events_table)
1747-
nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->loaded_json_aliases;
1773+
nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->cpu_json_aliases;
1774+
else
1775+
assert(pmu->cpu_json_aliases == 0);
17481776

17491777
return pmu->selectable ? nr + 1 : nr;
17501778
}

tools/perf/util/pmu.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,10 @@ struct perf_pmu {
123123
const struct pmu_events_table *events_table;
124124
/** @sysfs_aliases: Number of sysfs aliases loaded. */
125125
uint32_t sysfs_aliases;
126-
/** @sysfs_aliases: Number of json event aliases loaded. */
127-
uint32_t loaded_json_aliases;
126+
/** @cpu_json_aliases: Number of json event aliases loaded specific to the CPUID. */
127+
uint32_t cpu_json_aliases;
128+
/** @sys_json_aliases: Number of json event aliases loaded matching the PMU's identifier. */
129+
uint32_t sys_json_aliases;
128130
/** @sysfs_aliases_loaded: Are sysfs aliases loaded from disk? */
129131
bool sysfs_aliases_loaded;
130132
/**

0 commit comments

Comments
 (0)