write_backward attribute makes kernel filling ring buffer from the end of it, makes reading from overwrite ring buffer possible.
This patch select this attribute if evsel->overwrite is selected explicitly by user. Overwrite and write_backward are still controled separatly for legacy readonly mmap users (most of them are in perf/tests). Signed-off-by: Wang Nan <wangn...@huawei.com> Signed-off-by: He Kuang <heku...@huawei.com> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Jiri Olsa <jo...@kernel.org> Cc: Masami Hiramatsu <masami.hiramatsu...@hitachi.com> Cc: Namhyung Kim <namhy...@kernel.org> Cc: Zefan Li <lize...@huawei.com> Cc: pi3or...@163.com --- tools/perf/builtin-record.c | 7 +++++++ tools/perf/util/evlist.c | 2 ++ tools/perf/util/evlist.h | 1 + tools/perf/util/evsel.c | 13 +++++++++++++ 4 files changed, 23 insertions(+) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 56e796b..a069f75 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -333,6 +333,13 @@ static int record__open(struct record *rec) perf_evlist__config(evlist, opts); evlist__for_each(evlist, pos) { + if (pos->overwrite) { + if (!pos->attr.write_backward) { + ui__warning("Unable to read from overwrite ring buffer\n\n"); + rc = -ENOSYS; + goto out; + } + } try_again: if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c8112805..7877061 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -973,6 +973,8 @@ perf_evlist__channel_for_evsel(struct perf_evsel *evsel) if (evsel->overwrite) flag |= PERF_EVLIST__CHANNEL_RDONLY; + if (evsel->attr.write_backward) + flag |= PERF_EVLIST__CHANNEL_BACKWARD; return flag; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 21a8b85..321224c 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -24,6 +24,7 @@ struct record_opts; enum perf_evlist_mmap_flag { PERF_EVLIST__CHANNEL_ENABLED = 1, PERF_EVLIST__CHANNEL_RDONLY = 2, + PERF_EVLIST__CHANNEL_BACKWARD = 4, }; /** diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 10dfdd1..0bbd5ef 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -678,6 +678,19 @@ static void apply_config_terms(struct perf_evsel *evsel, } } + /* + * Set backward after config term processing because it is + * possible to set overwrite globally, without config + * terms. + */ + if (evsel->overwrite) { + if (opts->has_write_backward) + attr->write_backward = 1; + else + pr_err("Reading from overwrite event %s is not supported\n", + evsel->name); + } + /* User explicitly set per-event callgraph, clear the old setting and reset. */ if ((callgraph_buf != NULL) || (dump_size > 0)) { -- 1.8.3.4