diff options
author | Wang Nan <wangnan0@huawei.com> | 2016-05-23 03:13:41 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-05-23 17:22:48 -0400 |
commit | 3a62a7b8200a177ad96161e4f2678514e6ee301e (patch) | |
tree | b990cb212929775c1dc926ebc992dee6bbe7c03f /tools/perf | |
parent | 09fa4f401296f555afb6f2f4282717644d94722e (diff) |
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 <wangnan0@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1463987628-163563-5-git-send-email-wangnan0@huawei.com
Signed-off-by: He Kuang <hekuang@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-record.c | 52 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 1 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 1 |
3 files changed, 54 insertions, 0 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 73ce651c84f6..dc3fcb597e4c 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, | |||
83 | return record__write(rec, event, event->header.size); | 83 | return record__write(rec, event, event->header.size); |
84 | } | 84 | } |
85 | 85 | ||
86 | static int | ||
87 | backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end) | ||
88 | { | ||
89 | struct perf_event_header *pheader; | ||
90 | u64 evt_head = head; | ||
91 | int size = mask + 1; | ||
92 | |||
93 | pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head); | ||
94 | pheader = (struct perf_event_header *)(buf + (head & mask)); | ||
95 | *start = head; | ||
96 | while (true) { | ||
97 | if (evt_head - head >= (unsigned int)size) { | ||
98 | pr_debug("Finshed reading backward ring buffer: rewind\n"); | ||
99 | if (evt_head - head > (unsigned int)size) | ||
100 | evt_head -= pheader->size; | ||
101 | *end = evt_head; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | pheader = (struct perf_event_header *)(buf + (evt_head & mask)); | ||
106 | |||
107 | if (pheader->size == 0) { | ||
108 | pr_debug("Finshed reading backward ring buffer: get start\n"); | ||
109 | *end = evt_head; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | evt_head += pheader->size; | ||
114 | pr_debug3("move evt_head: %"PRIx64"\n", evt_head); | ||
115 | } | ||
116 | WARN_ONCE(1, "Shouldn't get here\n"); | ||
117 | return -1; | ||
118 | } | ||
119 | |||
120 | static int | ||
121 | rb_find_range(struct perf_evlist *evlist, | ||
122 | void *data, int mask, u64 head, u64 old, | ||
123 | u64 *start, u64 *end) | ||
124 | { | ||
125 | if (!evlist->backward) { | ||
126 | *start = old; | ||
127 | *end = head; | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | return backward_rb_find_range(data, mask, head, start, end); | ||
132 | } | ||
133 | |||
86 | static int record__mmap_read(struct record *rec, int idx) | 134 | static int record__mmap_read(struct record *rec, int idx) |
87 | { | 135 | { |
88 | struct perf_mmap *md = &rec->evlist->mmap[idx]; | 136 | struct perf_mmap *md = &rec->evlist->mmap[idx]; |
@@ -94,6 +142,10 @@ static int record__mmap_read(struct record *rec, int idx) | |||
94 | void *buf; | 142 | void *buf; |
95 | int rc = 0; | 143 | int rc = 0; |
96 | 144 | ||
145 | if (rb_find_range(rec->evlist, data, md->mask, head, | ||
146 | old, &start, &end)) | ||
147 | return -1; | ||
148 | |||
97 | if (start == end) | 149 | if (start == end) |
98 | return 0; | 150 | return 0; |
99 | 151 | ||
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 904523a2be90..e82ba90cc969 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, | |||
44 | perf_evlist__set_maps(evlist, cpus, threads); | 44 | perf_evlist__set_maps(evlist, cpus, threads); |
45 | fdarray__init(&evlist->pollfd, 64); | 45 | fdarray__init(&evlist->pollfd, 64); |
46 | evlist->workload.pid = -1; | 46 | evlist->workload.pid = -1; |
47 | evlist->backward = false; | ||
47 | } | 48 | } |
48 | 49 | ||
49 | struct perf_evlist *perf_evlist__new(void) | 50 | struct perf_evlist *perf_evlist__new(void) |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 97090b70976d..d740fb877ab6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -44,6 +44,7 @@ struct perf_evlist { | |||
44 | bool overwrite; | 44 | bool overwrite; |
45 | bool enabled; | 45 | bool enabled; |
46 | bool has_user_cpus; | 46 | bool has_user_cpus; |
47 | bool backward; | ||
47 | size_t mmap_len; | 48 | size_t mmap_len; |
48 | int id_pos; | 49 | int id_pos; |
49 | int is_pos; | 50 | int is_pos; |