Skip to content

Commit 0c9f790

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-core-for-mingo-20160523' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements from Arnaldo Carvalho de Melo: User visible changes: - Add "srcline_from" and "srcline_to" branch sort keys to 'perf top' and 'perf report' (Andi Kleen) Infrastructure changes: - Make 'perf trace' auto-attach fd->name and ptr->name beautifiers based on the name of syscall arguments, this way new syscalls that have 'const char * (path,pathname,filename)' will use the fd->name beautifier (vfs_getname perf probe, if in place) and the 'fd->name' (vfs_getname or via /proc/PID/fd/) (Arnaldo Carvalho de Melo) - Infrastructure to read from a ring buffer in backward write mode (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents 408cf67 + 3a62a7b commit 0c9f790

File tree

12 files changed

+319
-164
lines changed

12 files changed

+319
-164
lines changed

tools/perf/Documentation/perf-report.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,13 @@ OPTIONS
103103

104104
If --branch-stack option is used, following sort keys are also
105105
available:
106-
dso_from, dso_to, symbol_from, symbol_to, mispredict.
107106

108107
- dso_from: name of library or module branched from
109108
- dso_to: name of library or module branched to
110109
- symbol_from: name of function branched from
111110
- symbol_to: name of function branched to
111+
- srcline_from: source file and line branched from
112+
- srcline_to: source file and line branched to
112113
- mispredict: "N" for predicted branch, "Y" for mispredicted branch
113114
- in_tx: branch in TSX transaction
114115
- abort: TSX transaction abort.

tools/perf/builtin-record.c

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <unistd.h>
4141
#include <sched.h>
4242
#include <sys/mman.h>
43+
#include <asm/bug.h>
4344

4445

4546
struct record {
@@ -82,44 +83,104 @@ static int process_synthesized_event(struct perf_tool *tool,
8283
return record__write(rec, event, event->header.size);
8384
}
8485

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+
85134
static int record__mmap_read(struct record *rec, int idx)
86135
{
87136
struct perf_mmap *md = &rec->evlist->mmap[idx];
88137
u64 head = perf_mmap__read_head(md);
89138
u64 old = md->prev;
139+
u64 end = head, start = old;
90140
unsigned char *data = md->base + page_size;
91141
unsigned long size;
92142
void *buf;
93143
int rc = 0;
94144

95-
if (old == head)
145+
if (rb_find_range(rec->evlist, data, md->mask, head,
146+
old, &start, &end))
147+
return -1;
148+
149+
if (start == end)
96150
return 0;
97151

98152
rec->samples++;
99153

100-
size = head - old;
154+
size = end - start;
155+
if (size > (unsigned long)(md->mask) + 1) {
156+
WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
157+
158+
md->prev = head;
159+
perf_evlist__mmap_consume(rec->evlist, idx);
160+
return 0;
161+
}
101162

102-
if ((old & md->mask) + size != (head & md->mask)) {
103-
buf = &data[old & md->mask];
104-
size = md->mask + 1 - (old & md->mask);
105-
old += size;
163+
if ((start & md->mask) + size != (end & md->mask)) {
164+
buf = &data[start & md->mask];
165+
size = md->mask + 1 - (start & md->mask);
166+
start += size;
106167

107168
if (record__write(rec, buf, size) < 0) {
108169
rc = -1;
109170
goto out;
110171
}
111172
}
112173

113-
buf = &data[old & md->mask];
114-
size = head - old;
115-
old += size;
174+
buf = &data[start & md->mask];
175+
size = end - start;
176+
start += size;
116177

117178
if (record__write(rec, buf, size) < 0) {
118179
rc = -1;
119180
goto out;
120181
}
121182

122-
md->prev = old;
183+
md->prev = head;
123184
perf_evlist__mmap_consume(rec->evlist, idx);
124185
out:
125186
return rc;

0 commit comments

Comments
 (0)