Skip to content

Commit d685819

Browse files
captain5050namhyung
authored andcommitted
perf pmus: Add notion of default PMU for JSON events
JSON events created in pmu-events.c by jevents.py may not specify a PMU they are associated with, in which case it is implied that it is the first core PMU. Care is needed to select this for regular 'cpu', s390 'cpum_cf' and ARMs many names as at the point the name is first needed the core PMUs list hasn't been initialized. Add a helper in perf_pmus to create this value, in the worst case by scanning sysfs. v2. Add missing close if fdopendir fails. Signed-off-by: Ian Rogers <[email protected]> Tested-by: Thomas Richter <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: James Clark <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Thomas Richter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Kan Liang <[email protected]> Cc: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Namhyung Kim <[email protected]>
1 parent 33941db commit d685819

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

tools/perf/util/pmu.c

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -741,9 +741,11 @@ static bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
741741
}
742742

743743
struct pmu_add_cpu_aliases_map_data {
744+
/* List being added to. */
744745
struct list_head *head;
745-
const char *name;
746-
const char *cpu_name;
746+
/* If a pmu_event lacks a given PMU the default used. */
747+
char *default_pmu_name;
748+
/* The PMU that we're searching for events for. */
747749
struct perf_pmu *pmu;
748750
};
749751

@@ -752,37 +754,32 @@ static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe,
752754
void *vdata)
753755
{
754756
struct pmu_add_cpu_aliases_map_data *data = vdata;
755-
const char *pname = pe->pmu ? pe->pmu : data->cpu_name;
757+
const char *pname = pe->pmu ?: data->default_pmu_name;
756758

757-
if (data->pmu->is_uncore && pmu_uncore_alias_match(pname, data->name))
758-
goto new_alias;
759-
760-
if (strcmp(pname, data->name))
761-
return 0;
762-
763-
new_alias:
764-
/* need type casts to override 'const' */
765-
__perf_pmu__new_alias(data->head, -1, (char *)pe->name, (char *)pe->desc,
766-
(char *)pe->event, pe);
759+
if (!strcmp(pname, data->pmu->name) ||
760+
(data->pmu->is_uncore && pmu_uncore_alias_match(pname, data->pmu->name))) {
761+
/* need type casts to override 'const' */
762+
__perf_pmu__new_alias(data->head, -1, (char *)pe->name, (char *)pe->desc,
763+
(char *)pe->event, pe);
764+
}
767765
return 0;
768766
}
769767

770768
/*
771-
* From the pmu_events_map, find the table of PMU events that corresponds
772-
* to the current running CPU. Then, add all PMU events from that table
773-
* as aliases.
769+
* From the pmu_events_table, find the events that correspond to the given
770+
* PMU and add them to the list 'head'.
774771
*/
775772
void pmu_add_cpu_aliases_table(struct list_head *head, struct perf_pmu *pmu,
776-
const struct pmu_events_table *table)
773+
const struct pmu_events_table *table)
777774
{
778775
struct pmu_add_cpu_aliases_map_data data = {
779776
.head = head,
780-
.name = pmu->name,
781-
.cpu_name = is_sysfs_pmu_core(pmu->name) ? pmu->name : "cpu",
777+
.default_pmu_name = perf_pmus__default_pmu_name(),
782778
.pmu = pmu,
783779
};
784780

785781
pmu_events_table_for_each_event(table, pmu_add_cpu_aliases_map_callback, &data);
782+
free(data.default_pmu_name);
786783
}
787784

788785
static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)

tools/perf/util/pmus.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,10 @@ static void pmu_read_sysfs(bool core_only)
137137
return;
138138

139139
dir = fdopendir(fd);
140-
if (!dir)
140+
if (!dir) {
141+
close(fd);
141142
return;
143+
}
142144

143145
while ((dent = readdir(dir))) {
144146
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
@@ -524,6 +526,39 @@ bool perf_pmus__supports_extended_type(void)
524526
return perf_pmus__do_support_extended_type;
525527
}
526528

529+
char *perf_pmus__default_pmu_name(void)
530+
{
531+
int fd;
532+
DIR *dir;
533+
struct dirent *dent;
534+
char *result = NULL;
535+
536+
if (!list_empty(&core_pmus))
537+
return strdup(list_first_entry(&core_pmus, struct perf_pmu, list)->name);
538+
539+
fd = perf_pmu__event_source_devices_fd();
540+
if (fd < 0)
541+
return strdup("cpu");
542+
543+
dir = fdopendir(fd);
544+
if (!dir) {
545+
close(fd);
546+
return strdup("cpu");
547+
}
548+
549+
while ((dent = readdir(dir))) {
550+
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
551+
continue;
552+
if (is_pmu_core(dent->d_name)) {
553+
result = strdup(dent->d_name);
554+
break;
555+
}
556+
}
557+
558+
closedir(dir);
559+
return result ?: strdup("cpu");
560+
}
561+
527562
struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
528563
{
529564
struct perf_pmu *pmu = evsel->pmu;

tools/perf/util/pmus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *p
2020
bool perf_pmus__have_event(const char *pname, const char *name);
2121
int perf_pmus__num_core_pmus(void);
2222
bool perf_pmus__supports_extended_type(void);
23+
char *perf_pmus__default_pmu_name(void);
2324

2425
#endif /* __PMUS_H */

0 commit comments

Comments
 (0)