diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/evsel.c | 28 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 3 |
2 files changed, 31 insertions, 0 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ee6ee3f45c2..0c88e5c12da 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1378,3 +1378,31 @@ int perf_evsel__fprintf(struct perf_evsel *evsel, fputc('\n', fp); return ++printed; } + +bool perf_evsel__fallback(struct perf_evsel *evsel, int err, + char *msg, size_t msgsize) +{ + if ((err == ENOENT || err == ENXIO) && + evsel->attr.type == PERF_TYPE_HARDWARE && + evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES) { + /* + * If it's cycles then fall back to hrtimer based + * cpu-clock-tick sw counter, which is always available even if + * no PMU support. + * + * PPC returns ENXIO until 2.6.37 (behavior changed with commit + * b0a873e). + */ + scnprintf(msg, msgsize, "%s", +"The cycles event is not supported, trying to fall back to cpu-clock-ticks"); + + evsel->attr.type = PERF_TYPE_SOFTWARE; + evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; + + free(evsel->name); + evsel->name = NULL; + return true; + } + + return false; +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 9cb8a021571..26d8cfd86e0 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -251,4 +251,7 @@ struct perf_attr_details { int perf_evsel__fprintf(struct perf_evsel *evsel, struct perf_attr_details *details, FILE *fp); + +bool perf_evsel__fallback(struct perf_evsel *evsel, int err, + char *msg, size_t msgsize); #endif /* __PERF_EVSEL_H */ |