From: Kan Liang <kan.li...@intel.com>

Switch to non-overwrite mode if kernel doesnot support overwrite
ringbuffer.

It's only effect when overwrite mode is supported.
No change to current behavior.

Signed-off-by: Kan Liang <kan.li...@intel.com>
---
 tools/perf/builtin-top.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 4b85e7b..8d19ef7 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -931,6 +931,27 @@ static int perf_top_overwrite_check(struct perf_top *top)
        return 0;
 }
 
+static int perf_top_overwrite_fallback(struct perf_top *top,
+                                      struct perf_evsel *evsel)
+{
+       struct record_opts *opts = &top->record_opts;
+       struct perf_evlist *evlist = top->evlist;
+       struct perf_evsel *counter;
+
+       if (!opts->overwrite)
+               return 0;
+
+       /* only fall back when first event fails */
+       if (evsel != perf_evlist__first(evlist))
+               return 0;
+
+       evlist__for_each_entry(evlist, counter)
+               counter->attr.write_backward = false;
+       opts->overwrite = false;
+       ui__warning("fall back to non-overwrite mode\n");
+       return 1;
+}
+
 static int perf_top__start_counters(struct perf_top *top)
 {
        char msg[BUFSIZ];
@@ -954,6 +975,21 @@ static int perf_top__start_counters(struct perf_top *top)
 try_again:
                if (perf_evsel__open(counter, top->evlist->cpus,
                                     top->evlist->threads) < 0) {
+
+                       /*
+                        * Specially handle overwrite fall back.
+                        * Because perf top is the only tool which has
+                        * overwrite mode by default, support
+                        * both overwrite and non-overwrite mode, and
+                        * require consistent mode for all events.
+                        *
+                        * May move it to generic code with more tools
+                        * have similar attribute.
+                        */
+                       if (is_write_backward_fail() &&
+                           perf_top_overwrite_fallback(top, counter))
+                               goto try_again;
+
                        if (perf_evsel__fallback(counter, errno, msg, 
sizeof(msg))) {
                                if (verbose > 0)
                                        ui__warning("%s\n", msg);
-- 
2.5.5

Reply via email to