Skip to content

Commit 3a62a7b

Browse files
WangNan0acmel
authored andcommitted
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 <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Zefan Li <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: He Kuang <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 09fa4f4 commit 3a62a7b

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

tools/perf/builtin-record.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,54 @@ static int process_synthesized_event(struct perf_tool *tool,
8383
return record__write(rec, event, event->header.size);
8484
}
8585

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+
86134
static int record__mmap_read(struct record *rec, int idx)
87135
{
88136
struct perf_mmap *md = &rec->evlist->mmap[idx];
@@ -94,6 +142,10 @@ static int record__mmap_read(struct record *rec, int idx)
94142
void *buf;
95143
int rc = 0;
96144

145+
if (rb_find_range(rec->evlist, data, md->mask, head,
146+
old, &start, &end))
147+
return -1;
148+
97149
if (start == end)
98150
return 0;
99151

tools/perf/util/evlist.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
4444
perf_evlist__set_maps(evlist, cpus, threads);
4545
fdarray__init(&evlist->pollfd, 64);
4646
evlist->workload.pid = -1;
47+
evlist->backward = false;
4748
}
4849

4950
struct perf_evlist *perf_evlist__new(void)

tools/perf/util/evlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct perf_evlist {
4444
bool overwrite;
4545
bool enabled;
4646
bool has_user_cpus;
47+
bool backward;
4748
size_t mmap_len;
4849
int id_pos;
4950
int is_pos;

0 commit comments

Comments
 (0)