Commit-ID:  3a62a7b8200a177ad96161e4f2678514e6ee301e
Gitweb:     http://git.kernel.org/tip/3a62a7b8200a177ad96161e4f2678514e6ee301e
Author:     Wang Nan <wangn...@huawei.com>
AuthorDate: Mon, 23 May 2016 07:13:41 +0000
Committer:  Arnaldo Carvalho de Melo <a...@redhat.com>
CommitDate: Mon, 23 May 2016 18:22:48 -0300

perf record: Read from backward ring buffer

Introduce rb_find_range() to find start and end position from a backward
ring buffer.

Signed-off-by: Wang Nan <wangn...@huawei.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
Link: 
http://lkml.kernel.org/r/1463987628-163563-5-git-send-email-wangn...@huawei.com
Signed-off-by: He Kuang <heku...@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/builtin-record.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/evlist.c    |  1 +
 tools/perf/util/evlist.h    |  1 +
 3 files changed, 54 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 73ce651..dc3fcb5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -83,6 +83,54 @@ static int process_synthesized_event(struct perf_tool *tool,
        return record__write(rec, event, event->header.size);
 }
 
+static int
+backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
+{
+       struct perf_event_header *pheader;
+       u64 evt_head = head;
+       int size = mask + 1;
+
+       pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, 
head);
+       pheader = (struct perf_event_header *)(buf + (head & mask));
+       *start = head;
+       while (true) {
+               if (evt_head - head >= (unsigned int)size) {
+                       pr_debug("Finshed reading backward ring buffer: 
rewind\n");
+                       if (evt_head - head > (unsigned int)size)
+                               evt_head -= pheader->size;
+                       *end = evt_head;
+                       return 0;
+               }
+
+               pheader = (struct perf_event_header *)(buf + (evt_head & mask));
+
+               if (pheader->size == 0) {
+                       pr_debug("Finshed reading backward ring buffer: get 
start\n");
+                       *end = evt_head;
+                       return 0;
+               }
+
+               evt_head += pheader->size;
+               pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
+       }
+       WARN_ONCE(1, "Shouldn't get here\n");
+       return -1;
+}
+
+static int
+rb_find_range(struct perf_evlist *evlist,
+             void *data, int mask, u64 head, u64 old,
+             u64 *start, u64 *end)
+{
+       if (!evlist->backward) {
+               *start = old;
+               *end = head;
+               return 0;
+       }
+
+       return backward_rb_find_range(data, mask, head, start, end);
+}
+
 static int record__mmap_read(struct record *rec, int idx)
 {
        struct perf_mmap *md = &rec->evlist->mmap[idx];
@@ -94,6 +142,10 @@ static int record__mmap_read(struct record *rec, int idx)
        void *buf;
        int rc = 0;
 
+       if (rb_find_range(rec->evlist, data, md->mask, head,
+                         old, &start, &end))
+               return -1;
+
        if (start == end)
                return 0;
 
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 904523a..e82ba90 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -44,6 +44,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct 
cpu_map *cpus,
        perf_evlist__set_maps(evlist, cpus, threads);
        fdarray__init(&evlist->pollfd, 64);
        evlist->workload.pid = -1;
+       evlist->backward = false;
 }
 
 struct perf_evlist *perf_evlist__new(void)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 97090b7..d740fb8 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -44,6 +44,7 @@ struct perf_evlist {
        bool             overwrite;
        bool             enabled;
        bool             has_user_cpus;
+       bool             backward;
        size_t           mmap_len;
        int              id_pos;
        int              is_pos;

Reply via email to