perf evsel: Introduce event fallback method
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 13 Dec 2012 17:16:30 +0000 (14:16 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 24 Jan 2013 19:40:08 +0000 (16:40 -0300)
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>
tools/perf/builtin-record.c
tools/perf/builtin-top.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h

index a4b97269cfc6220d8f0470fd41bad9aedd3f60fc..b8d0a39b484e889b004f3bf21b488ec510fb0591 100644 (file)
@@ -224,6 +224,7 @@ static bool perf_evlist__equal(struct perf_evlist *evlist,
 
 static int perf_record__open(struct perf_record *rec)
 {
+       char msg[128];
        struct perf_evsel *pos;
        struct perf_evlist *evlist = rec->evlist;
        struct perf_session *session = rec->session;
@@ -249,27 +250,9 @@ try_again:
                                goto out;
                        }
 
-                       /*
-                        * 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).
-                        */
-                       if ((err == ENOENT || err == ENXIO)
-                                       && attr->type == PERF_TYPE_HARDWARE
-                                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
+                       if (perf_evsel__fallback(pos, err, msg, sizeof(msg))) {
                                if (verbose)
-                                       ui__warning("The cycles event is not supported, "
-                                                   "trying to fall back to cpu-clock-ticks\n");
-                               attr->type = PERF_TYPE_SOFTWARE;
-                               attr->config = PERF_COUNT_SW_CPU_CLOCK;
-                               if (pos->name) {
-                                       free(pos->name);
-                                       pos->name = NULL;
-                               }
+                                       ui__warning("%s\n", msg);
                                goto try_again;
                        }
 
index 74fca619fc4e2d076662cb801cdf8129730e48ea..8d41d0b589568458c057fa41f0eb9bfcd61de074 100644 (file)
@@ -892,6 +892,7 @@ static void perf_top__mmap_read(struct perf_top *top)
 
 static void perf_top__start_counters(struct perf_top *top)
 {
+       char msg[128];
        struct perf_evsel *counter;
        struct perf_evlist *evlist = top->evlist;
        struct perf_record_opts *opts = &top->record_opts;
@@ -909,25 +910,10 @@ try_again:
                                ui__error_paranoid();
                                goto out_err;
                        }
-                       /*
-                        * If it's cycles then fall back to hrtimer
-                        * based cpu-clock-tick sw counter, which
-                        * is always available even if no PMU support:
-                        */
-                       if ((err == ENOENT || err == ENXIO) &&
-                           (attr->type == PERF_TYPE_HARDWARE) &&
-                           (attr->config == PERF_COUNT_HW_CPU_CYCLES)) {
 
+                       if (perf_evsel__fallback(counter, err, msg, sizeof(msg))) {
                                if (verbose)
-                                       ui__warning("Cycles event not supported,\n"
-                                                   "trying to fall back to cpu-clock-ticks\n");
-
-                               attr->type = PERF_TYPE_SOFTWARE;
-                               attr->config = PERF_COUNT_SW_CPU_CLOCK;
-                               if (counter->name) {
-                                       free(counter->name);
-                                       counter->name = NULL;
-                               }
+                                       ui__warning("%s\n", msg);
                                goto try_again;
                        }
 
index ee6ee3f45c2ab08471e6d66c90a71ce35a9690a6..0c88e5c12dabc9fecb8f3c33344395a63ac46124 100644 (file)
@@ -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;
+}
index 9cb8a02157110cd9d8aac124e78c423d22f50bc0..26d8cfd86e0ad14a04af7b102cb78690247062b3 100644 (file)
@@ -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 */