diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-11-11 07:44:09 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-11-11 13:56:39 -0500 |
commit | 62605dc50c27bf0e4ff69b7b3166f226586aff02 (patch) | |
tree | e858c9a71749a3d280b25a7ab7928dcbeba51a73 /tools/perf/util | |
parent | ef503831d8d64e12c6dad5547875cfcd4c5d043c (diff) |
perf record: Synthesize non-exec MMAP records when --data used
When perf_event_attr.mmap_data is set the kernel will generate
PERF_RECORD_MMAP events when non-exec (data, SysV mem) mmaps are
created, so we need to synthesize from /proc/pid/maps for existing
threads, as we do for exec mmaps.
Right now just 'perf record' does it, but any other tool that uses
perf_event__synthesize_thread(s|map) can request it.
Reported-by: Don Zickus <dzickus@redhat.com>
Tested-by: Don Zickus <dzickus@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Bill Gray <bgray@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Joe Mario <jmario@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Richard Fowles <rfowles@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-ihwzraikx23ian9txinogvv2@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/event.c | 50 | ||||
-rw-r--r-- | tools/perf/util/event.h | 4 |
2 files changed, 32 insertions, 22 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ec9ae1114ed4..6e3a846aed0e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -170,7 +170,8 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
170 | union perf_event *event, | 170 | union perf_event *event, |
171 | pid_t pid, pid_t tgid, | 171 | pid_t pid, pid_t tgid, |
172 | perf_event__handler_t process, | 172 | perf_event__handler_t process, |
173 | struct machine *machine) | 173 | struct machine *machine, |
174 | bool mmap_data) | ||
174 | { | 175 | { |
175 | char filename[PATH_MAX]; | 176 | char filename[PATH_MAX]; |
176 | FILE *fp; | 177 | FILE *fp; |
@@ -188,10 +189,6 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
188 | } | 189 | } |
189 | 190 | ||
190 | event->header.type = PERF_RECORD_MMAP; | 191 | event->header.type = PERF_RECORD_MMAP; |
191 | /* | ||
192 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | ||
193 | */ | ||
194 | event->header.misc = PERF_RECORD_MISC_USER; | ||
195 | 192 | ||
196 | while (1) { | 193 | while (1) { |
197 | char bf[BUFSIZ]; | 194 | char bf[BUFSIZ]; |
@@ -215,9 +212,17 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
215 | 212 | ||
216 | if (n != 5) | 213 | if (n != 5) |
217 | continue; | 214 | continue; |
215 | /* | ||
216 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | ||
217 | */ | ||
218 | event->header.misc = PERF_RECORD_MISC_USER; | ||
218 | 219 | ||
219 | if (prot[2] != 'x') | 220 | if (prot[2] != 'x') { |
220 | continue; | 221 | if (!mmap_data || prot[0] != 'r') |
222 | continue; | ||
223 | |||
224 | event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; | ||
225 | } | ||
221 | 226 | ||
222 | if (!strcmp(execname, "")) | 227 | if (!strcmp(execname, "")) |
223 | strcpy(execname, anonstr); | 228 | strcpy(execname, anonstr); |
@@ -304,20 +309,21 @@ static int __event__synthesize_thread(union perf_event *comm_event, | |||
304 | pid_t pid, int full, | 309 | pid_t pid, int full, |
305 | perf_event__handler_t process, | 310 | perf_event__handler_t process, |
306 | struct perf_tool *tool, | 311 | struct perf_tool *tool, |
307 | struct machine *machine) | 312 | struct machine *machine, bool mmap_data) |
308 | { | 313 | { |
309 | pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full, | 314 | pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full, |
310 | process, machine); | 315 | process, machine); |
311 | if (tgid == -1) | 316 | if (tgid == -1) |
312 | return -1; | 317 | return -1; |
313 | return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, | 318 | return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, |
314 | process, machine); | 319 | process, machine, mmap_data); |
315 | } | 320 | } |
316 | 321 | ||
317 | int perf_event__synthesize_thread_map(struct perf_tool *tool, | 322 | int perf_event__synthesize_thread_map(struct perf_tool *tool, |
318 | struct thread_map *threads, | 323 | struct thread_map *threads, |
319 | perf_event__handler_t process, | 324 | perf_event__handler_t process, |
320 | struct machine *machine) | 325 | struct machine *machine, |
326 | bool mmap_data) | ||
321 | { | 327 | { |
322 | union perf_event *comm_event, *mmap_event; | 328 | union perf_event *comm_event, *mmap_event; |
323 | int err = -1, thread, j; | 329 | int err = -1, thread, j; |
@@ -334,7 +340,8 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, | |||
334 | for (thread = 0; thread < threads->nr; ++thread) { | 340 | for (thread = 0; thread < threads->nr; ++thread) { |
335 | if (__event__synthesize_thread(comm_event, mmap_event, | 341 | if (__event__synthesize_thread(comm_event, mmap_event, |
336 | threads->map[thread], 0, | 342 | threads->map[thread], 0, |
337 | process, tool, machine)) { | 343 | process, tool, machine, |
344 | mmap_data)) { | ||
338 | err = -1; | 345 | err = -1; |
339 | break; | 346 | break; |
340 | } | 347 | } |
@@ -356,10 +363,10 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, | |||
356 | 363 | ||
357 | /* if not, generate events for it */ | 364 | /* if not, generate events for it */ |
358 | if (need_leader && | 365 | if (need_leader && |
359 | __event__synthesize_thread(comm_event, | 366 | __event__synthesize_thread(comm_event, mmap_event, |
360 | mmap_event, | 367 | comm_event->comm.pid, 0, |
361 | comm_event->comm.pid, 0, | 368 | process, tool, machine, |
362 | process, tool, machine)) { | 369 | mmap_data)) { |
363 | err = -1; | 370 | err = -1; |
364 | break; | 371 | break; |
365 | } | 372 | } |
@@ -374,7 +381,7 @@ out: | |||
374 | 381 | ||
375 | int perf_event__synthesize_threads(struct perf_tool *tool, | 382 | int perf_event__synthesize_threads(struct perf_tool *tool, |
376 | perf_event__handler_t process, | 383 | perf_event__handler_t process, |
377 | struct machine *machine) | 384 | struct machine *machine, bool mmap_data) |
378 | { | 385 | { |
379 | DIR *proc; | 386 | DIR *proc; |
380 | struct dirent dirent, *next; | 387 | struct dirent dirent, *next; |
@@ -404,7 +411,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
404 | * one thread couldn't be synthesized. | 411 | * one thread couldn't be synthesized. |
405 | */ | 412 | */ |
406 | __event__synthesize_thread(comm_event, mmap_event, pid, 1, | 413 | __event__synthesize_thread(comm_event, mmap_event, pid, 1, |
407 | process, tool, machine); | 414 | process, tool, machine, mmap_data); |
408 | } | 415 | } |
409 | 416 | ||
410 | err = 0; | 417 | err = 0; |
@@ -528,19 +535,22 @@ int perf_event__process_lost(struct perf_tool *tool __maybe_unused, | |||
528 | 535 | ||
529 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) | 536 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) |
530 | { | 537 | { |
531 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", | 538 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n", |
532 | event->mmap.pid, event->mmap.tid, event->mmap.start, | 539 | event->mmap.pid, event->mmap.tid, event->mmap.start, |
533 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); | 540 | event->mmap.len, event->mmap.pgoff, |
541 | (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', | ||
542 | event->mmap.filename); | ||
534 | } | 543 | } |
535 | 544 | ||
536 | size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) | 545 | size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) |
537 | { | 546 | { |
538 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 | 547 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 |
539 | " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n", | 548 | " %02x:%02x %"PRIu64" %"PRIu64"]: %c %s\n", |
540 | event->mmap2.pid, event->mmap2.tid, event->mmap2.start, | 549 | event->mmap2.pid, event->mmap2.tid, event->mmap2.start, |
541 | event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, | 550 | event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, |
542 | event->mmap2.min, event->mmap2.ino, | 551 | event->mmap2.min, event->mmap2.ino, |
543 | event->mmap2.ino_generation, | 552 | event->mmap2.ino_generation, |
553 | (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', | ||
544 | event->mmap2.filename); | 554 | event->mmap2.filename); |
545 | } | 555 | } |
546 | 556 | ||
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index f8d70f3003ab..30fec9901e44 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -208,10 +208,10 @@ typedef int (*perf_event__handler_t)(struct perf_tool *tool, | |||
208 | int perf_event__synthesize_thread_map(struct perf_tool *tool, | 208 | int perf_event__synthesize_thread_map(struct perf_tool *tool, |
209 | struct thread_map *threads, | 209 | struct thread_map *threads, |
210 | perf_event__handler_t process, | 210 | perf_event__handler_t process, |
211 | struct machine *machine); | 211 | struct machine *machine, bool mmap_data); |
212 | int perf_event__synthesize_threads(struct perf_tool *tool, | 212 | int perf_event__synthesize_threads(struct perf_tool *tool, |
213 | perf_event__handler_t process, | 213 | perf_event__handler_t process, |
214 | struct machine *machine); | 214 | struct machine *machine, bool mmap_data); |
215 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, | 215 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, |
216 | perf_event__handler_t process, | 216 | perf_event__handler_t process, |
217 | struct machine *machine, | 217 | struct machine *machine, |