diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-12-13 12:16:30 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-01-24 14:40:08 -0500 |
commit | c0a54341c0e89333ef201fc3f3001176962f6121 (patch) | |
tree | d43d2fcb1c49ae17cbf8cf9aa270694b88cf39e1 | |
parent | 594ac61ad3be9c80c738a9fe3bb95c05d8d1bae1 (diff) |
perf evsel: Introduce event fallback method
The only fallback right now is for HW cpu-cycles -> SW cpu-clock, that
was done in the same way in both 'top' and 'record'.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-58l1mgibh9oa9m0pd3fasxa5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-record.c | 23 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 20 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 28 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 3 |
4 files changed, 37 insertions, 37 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index a4b97269cfc6..b8d0a39b484e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -224,6 +224,7 @@ static bool perf_evlist__equal(struct perf_evlist *evlist, | |||
224 | 224 | ||
225 | static int perf_record__open(struct perf_record *rec) | 225 | static int perf_record__open(struct perf_record *rec) |
226 | { | 226 | { |
227 | char msg[128]; | ||
227 | struct perf_evsel *pos; | 228 | struct perf_evsel *pos; |
228 | struct perf_evlist *evlist = rec->evlist; | 229 | struct perf_evlist *evlist = rec->evlist; |
229 | struct perf_session *session = rec->session; | 230 | struct perf_session *session = rec->session; |
@@ -249,27 +250,9 @@ try_again: | |||
249 | goto out; | 250 | goto out; |
250 | } | 251 | } |
251 | 252 | ||
252 | /* | 253 | if (perf_evsel__fallback(pos, err, msg, sizeof(msg))) { |
253 | * If it's cycles then fall back to hrtimer | ||
254 | * based cpu-clock-tick sw counter, which | ||
255 | * is always available even if no PMU support. | ||
256 | * | ||
257 | * PPC returns ENXIO until 2.6.37 (behavior changed | ||
258 | * with commit b0a873e). | ||
259 | */ | ||
260 | if ((err == ENOENT || err == ENXIO) | ||
261 | && attr->type == PERF_TYPE_HARDWARE | ||
262 | && attr->config == PERF_COUNT_HW_CPU_CYCLES) { | ||
263 | |||
264 | if (verbose) | 254 | if (verbose) |
265 | ui__warning("The cycles event is not supported, " | 255 | ui__warning("%s\n", msg); |
266 | "trying to fall back to cpu-clock-ticks\n"); | ||
267 | attr->type = PERF_TYPE_SOFTWARE; | ||
268 | attr->config = PERF_COUNT_SW_CPU_CLOCK; | ||
269 | if (pos->name) { | ||
270 | free(pos->name); | ||
271 | pos->name = NULL; | ||
272 | } | ||
273 | goto try_again; | 256 | goto try_again; |
274 | } | 257 | } |
275 | 258 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 74fca619fc4e..8d41d0b58956 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -892,6 +892,7 @@ static void perf_top__mmap_read(struct perf_top *top) | |||
892 | 892 | ||
893 | static void perf_top__start_counters(struct perf_top *top) | 893 | static void perf_top__start_counters(struct perf_top *top) |
894 | { | 894 | { |
895 | char msg[128]; | ||
895 | struct perf_evsel *counter; | 896 | struct perf_evsel *counter; |
896 | struct perf_evlist *evlist = top->evlist; | 897 | struct perf_evlist *evlist = top->evlist; |
897 | struct perf_record_opts *opts = &top->record_opts; | 898 | struct perf_record_opts *opts = &top->record_opts; |
@@ -909,25 +910,10 @@ try_again: | |||
909 | ui__error_paranoid(); | 910 | ui__error_paranoid(); |
910 | goto out_err; | 911 | goto out_err; |
911 | } | 912 | } |
912 | /* | ||
913 | * If it's cycles then fall back to hrtimer | ||
914 | * based cpu-clock-tick sw counter, which | ||
915 | * is always available even if no PMU support: | ||
916 | */ | ||
917 | if ((err == ENOENT || err == ENXIO) && | ||
918 | (attr->type == PERF_TYPE_HARDWARE) && | ||
919 | (attr->config == PERF_COUNT_HW_CPU_CYCLES)) { | ||
920 | 913 | ||
914 | if (perf_evsel__fallback(counter, err, msg, sizeof(msg))) { | ||
921 | if (verbose) | 915 | if (verbose) |
922 | ui__warning("Cycles event not supported,\n" | 916 | ui__warning("%s\n", msg); |
923 | "trying to fall back to cpu-clock-ticks\n"); | ||
924 | |||
925 | attr->type = PERF_TYPE_SOFTWARE; | ||
926 | attr->config = PERF_COUNT_SW_CPU_CLOCK; | ||
927 | if (counter->name) { | ||
928 | free(counter->name); | ||
929 | counter->name = NULL; | ||
930 | } | ||
931 | goto try_again; | 917 | goto try_again; |
932 | } | 918 | } |
933 | 919 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ee6ee3f45c2a..0c88e5c12dab 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, | |||
1378 | fputc('\n', fp); | 1378 | fputc('\n', fp); |
1379 | return ++printed; | 1379 | return ++printed; |
1380 | } | 1380 | } |
1381 | |||
1382 | bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | ||
1383 | char *msg, size_t msgsize) | ||
1384 | { | ||
1385 | if ((err == ENOENT || err == ENXIO) && | ||
1386 | evsel->attr.type == PERF_TYPE_HARDWARE && | ||
1387 | evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES) { | ||
1388 | /* | ||
1389 | * If it's cycles then fall back to hrtimer based | ||
1390 | * cpu-clock-tick sw counter, which is always available even if | ||
1391 | * no PMU support. | ||
1392 | * | ||
1393 | * PPC returns ENXIO until 2.6.37 (behavior changed with commit | ||
1394 | * b0a873e). | ||
1395 | */ | ||
1396 | scnprintf(msg, msgsize, "%s", | ||
1397 | "The cycles event is not supported, trying to fall back to cpu-clock-ticks"); | ||
1398 | |||
1399 | evsel->attr.type = PERF_TYPE_SOFTWARE; | ||
1400 | evsel->attr.config = PERF_COUNT_SW_CPU_CLOCK; | ||
1401 | |||
1402 | free(evsel->name); | ||
1403 | evsel->name = NULL; | ||
1404 | return true; | ||
1405 | } | ||
1406 | |||
1407 | return false; | ||
1408 | } | ||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 9cb8a0215711..26d8cfd86e0a 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -251,4 +251,7 @@ struct perf_attr_details { | |||
251 | 251 | ||
252 | int perf_evsel__fprintf(struct perf_evsel *evsel, | 252 | int perf_evsel__fprintf(struct perf_evsel *evsel, |
253 | struct perf_attr_details *details, FILE *fp); | 253 | struct perf_attr_details *details, FILE *fp); |
254 | |||
255 | bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | ||
256 | char *msg, size_t msgsize); | ||
254 | #endif /* __PERF_EVSEL_H */ | 257 | #endif /* __PERF_EVSEL_H */ |