aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 13:28:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 13:28:49 -0400
commit7e92daaefa68e5ef1e1732e45231e73adbb724e7 (patch)
tree8e7f8ac9d82654df4c65939c6682f95510e22977 /tools/perf/util/event.c
parent7a68294278ae714ce2632a54f0f46916dca64f56 (diff)
parent1d787d37c8ff6612b8151c6dff15bfa7347bcbdf (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf update from Ingo Molnar: "Lots of changes in this cycle as well, with hundreds of commits from over 30 contributors. Most of the activity was on the tooling side. Higher level changes: - New 'perf kvm' analysis tool, from Xiao Guangrong. - New 'perf trace' system-wide tracing tool - uprobes fixes + cleanups from Oleg Nesterov. - Lots of patches to make perf build on Android out of box, from Irina Tirdea - Extend ftrace function tracing utility to be more dynamic for its users. It allows for data passing to the callback functions, as well as reading regs as if a breakpoint were to trigger at function entry. The main goal of this patch series was to allow kprobes to use ftrace as an optimized probe point when a probe is placed on an ftrace nop. With lots of help from Masami Hiramatsu, and going through lots of iterations, we finally came up with a good solution. - Add cpumask for uncore pmu, use it in 'stat', from Yan, Zheng. - Various tracing updates from Steve Rostedt - Clean up and improve 'perf sched' performance by elliminating lots of needless calls to libtraceevent. - Event group parsing support, from Jiri Olsa - UI/gtk refactorings and improvements from Namhyung Kim - Add support for non-tracepoint events in perf script python, from Feng Tang - Add --symbols to 'script', similar to the one in 'report', from Feng Tang. Infrastructure enhancements and fixes: - Convert the trace builtins to use the growing evsel/evlist tracepoint infrastructure, removing several open coded constructs like switch like series of strcmp to dispatch events, etc. Basically what had already been showcased in 'perf sched'. - Add evsel constructor for tracepoints, that uses libtraceevent just to parse the /format events file, use it in a new 'perf test' to make sure the libtraceevent format parsing regressions can be more readily caught. - Some strange errors were happening in some builds, but not on the next, reported by several people, problem was some parser related files, generated during the build, didn't had proper make deps, fix from Eric Sandeen. - Introduce struct and cache information about the environment where a perf.data file was captured, from Namhyung Kim. - Fix handling of unresolved samples when --symbols is used in 'report', from Feng Tang. - Add union member access support to 'probe', from Hyeoncheol Lee. - Fixups to die() removal, from Namhyung Kim. - Render fixes for the TUI, from Namhyung Kim. - Don't enable annotation in non symbolic view, from Namhyung Kim. - Fix pipe mode in 'report', from Namhyung Kim. - Move related stats code from stat to util/, will be used by the 'stat' kvm tool, from Xiao Guangrong. - Remove die()/exit() calls from several tools. - Resolve vdso callchains, from Jiri Olsa - Don't pass const char pointers to basename, so that we can unconditionally use libgen.h and thus avoid ifdef BIONIC lines, from David Ahern - Refactor hist formatting so that it can be reused with the GTK browser, From Namhyung Kim - Fix build for another rbtree.c change, from Adrian Hunter. - Make 'perf diff' command work with evsel hists, from Jiri Olsa. - Use the only field_sep var that is set up: symbol_conf.field_sep, fix from Jiri Olsa. - .gitignore compiled python binaries, from Namhyung Kim. - Get rid of die() in more libtraceevent places, from Namhyung Kim. - Rename libtraceevent 'private' struct member to 'priv' so that it works in C++, from Steven Rostedt - Remove lots of exit()/die() calls from tools so that the main perf exit routine can take place, from David Ahern - Fix x86 build on x86-64, from David Ahern. - {int,str,rb}list fixes from Suzuki K Poulose - perf.data header fixes from Namhyung Kim - Allow user to indicate objdump path, needed in cross environments, from Maciek Borzecki - Fix hardware cache event name generation, fix from Jiri Olsa - Add round trip test for sw, hw and cache event names, catching the problem Jiri fixed, after Jiri's patch, the test passes successfully. - Clean target should do clean for lib/traceevent too, fix from David Ahern - Check the right variable for allocation failure, fix from Namhyung Kim - Set up evsel->tp_format regardless of evsel->name being set already, fix from Namhyung Kim - Oprofile fixes from Robert Richter. - Remove perf_event_attr needless version inflation, from Jiri Olsa - Introduce libtraceevent strerror like error reporting facility, from Namhyung Kim - Add pmu mappings to perf.data header and use event names from cmd line, from Robert Richter - Fix include order for bison/flex-generated C files, from Ben Hutchings - Build fixes and documentation corrections from David Ahern - Assorted cleanups from Robert Richter - Let O= makes handle relative paths, from Steven Rostedt - perf script python fixes, from Feng Tang. - Initial bash completion support, from Frederic Weisbecker - Allow building without libelf, from Namhyung Kim. - Support DWARF CFI based unwind to have callchains when %bp based unwinding is not possible, from Jiri Olsa. - Symbol resolution fixes, while fixing support PPC64 files with an .opt ELF section was the end goal, several fixes for code that handles all architectures and cleanups are included, from Cody Schafer. - Assorted fixes for Documentation and build in 32 bit, from Robert Richter - Cache the libtraceevent event_format associated to each evsel early, so that we avoid relookups, i.e. calling pevent_find_event repeatedly when processing tracepoint events. [ This is to reduce the surface contact with libtraceevents and make clear what is that the perf tools needs from that lib: so far parsing the common and per event fields. ] - Don't stop the build if the audit libraries are not installed, fix from Namhyung Kim. - Fix bfd.h/libbfd detection with recent binutils, from Markus Trippelsdorf. - Improve warning message when libunwind devel packages not present, from Jiri Olsa" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (282 commits) perf trace: Add aliases for some syscalls perf probe: Print an enum type variable in "enum variable-name" format when showing accessible variables perf tools: Check libaudit availability for perf-trace builtin perf hists: Add missing period_* fields when collapsing a hist entry perf trace: New tool perf evsel: Export the event_format constructor perf evsel: Introduce rawptr() method perf tools: Use perf_evsel__newtp in the event parser perf evsel: The tracepoint constructor should store sys:name perf evlist: Introduce set_filter() method perf evlist: Renane set_filters method to apply_filters perf test: Add test to check we correctly parse and match syscall open parms perf evsel: Handle endianity in intval method perf evsel: Know if byte swap is needed perf tools: Allow handling a NULL cpu_map as meaning "all cpus" perf evsel: Improve tracepoint constructor setup tools lib traceevent: Fix error path on pevent_parse_event perf test: Fix build failure trace: Move trace event enable from fs_initcall to core_initcall tracing: Add an option for disabling markers ...
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2a6f33cd888c..6715b1938725 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -112,7 +112,7 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
112 event->comm.header.type = PERF_RECORD_COMM; 112 event->comm.header.type = PERF_RECORD_COMM;
113 113
114 size = strlen(event->comm.comm) + 1; 114 size = strlen(event->comm.comm) + 1;
115 size = ALIGN(size, sizeof(u64)); 115 size = PERF_ALIGN(size, sizeof(u64));
116 memset(event->comm.comm + size, 0, machine->id_hdr_size); 116 memset(event->comm.comm + size, 0, machine->id_hdr_size);
117 event->comm.header.size = (sizeof(event->comm) - 117 event->comm.header.size = (sizeof(event->comm) -
118 (sizeof(event->comm.comm) - size) + 118 (sizeof(event->comm.comm) - size) +
@@ -120,7 +120,9 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
120 if (!full) { 120 if (!full) {
121 event->comm.tid = pid; 121 event->comm.tid = pid;
122 122
123 process(tool, event, &synth_sample, machine); 123 if (process(tool, event, &synth_sample, machine) != 0)
124 return -1;
125
124 goto out; 126 goto out;
125 } 127 }
126 128
@@ -143,7 +145,7 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
143 sizeof(event->comm.comm)); 145 sizeof(event->comm.comm));
144 146
145 size = strlen(event->comm.comm) + 1; 147 size = strlen(event->comm.comm) + 1;
146 size = ALIGN(size, sizeof(u64)); 148 size = PERF_ALIGN(size, sizeof(u64));
147 memset(event->comm.comm + size, 0, machine->id_hdr_size); 149 memset(event->comm.comm + size, 0, machine->id_hdr_size);
148 event->comm.header.size = (sizeof(event->comm) - 150 event->comm.header.size = (sizeof(event->comm) -
149 (sizeof(event->comm.comm) - size) + 151 (sizeof(event->comm.comm) - size) +
@@ -151,7 +153,10 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
151 153
152 event->comm.tid = pid; 154 event->comm.tid = pid;
153 155
154 process(tool, event, &synth_sample, machine); 156 if (process(tool, event, &synth_sample, machine) != 0) {
157 tgid = -1;
158 break;
159 }
155 } 160 }
156 161
157 closedir(tasks); 162 closedir(tasks);
@@ -167,6 +172,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
167{ 172{
168 char filename[PATH_MAX]; 173 char filename[PATH_MAX];
169 FILE *fp; 174 FILE *fp;
175 int rc = 0;
170 176
171 snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); 177 snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
172 178
@@ -222,7 +228,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
222 size = strlen(execname); 228 size = strlen(execname);
223 execname[size - 1] = '\0'; /* Remove \n */ 229 execname[size - 1] = '\0'; /* Remove \n */
224 memcpy(event->mmap.filename, execname, size); 230 memcpy(event->mmap.filename, execname, size);
225 size = ALIGN(size, sizeof(u64)); 231 size = PERF_ALIGN(size, sizeof(u64));
226 event->mmap.len -= event->mmap.start; 232 event->mmap.len -= event->mmap.start;
227 event->mmap.header.size = (sizeof(event->mmap) - 233 event->mmap.header.size = (sizeof(event->mmap) -
228 (sizeof(event->mmap.filename) - size)); 234 (sizeof(event->mmap.filename) - size));
@@ -231,18 +237,22 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
231 event->mmap.pid = tgid; 237 event->mmap.pid = tgid;
232 event->mmap.tid = pid; 238 event->mmap.tid = pid;
233 239
234 process(tool, event, &synth_sample, machine); 240 if (process(tool, event, &synth_sample, machine) != 0) {
241 rc = -1;
242 break;
243 }
235 } 244 }
236 } 245 }
237 246
238 fclose(fp); 247 fclose(fp);
239 return 0; 248 return rc;
240} 249}
241 250
242int perf_event__synthesize_modules(struct perf_tool *tool, 251int perf_event__synthesize_modules(struct perf_tool *tool,
243 perf_event__handler_t process, 252 perf_event__handler_t process,
244 struct machine *machine) 253 struct machine *machine)
245{ 254{
255 int rc = 0;
246 struct rb_node *nd; 256 struct rb_node *nd;
247 struct map_groups *kmaps = &machine->kmaps; 257 struct map_groups *kmaps = &machine->kmaps;
248 union perf_event *event = zalloc((sizeof(event->mmap) + 258 union perf_event *event = zalloc((sizeof(event->mmap) +
@@ -272,7 +282,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
272 if (pos->dso->kernel) 282 if (pos->dso->kernel)
273 continue; 283 continue;
274 284
275 size = ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); 285 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
276 event->mmap.header.type = PERF_RECORD_MMAP; 286 event->mmap.header.type = PERF_RECORD_MMAP;
277 event->mmap.header.size = (sizeof(event->mmap) - 287 event->mmap.header.size = (sizeof(event->mmap) -
278 (sizeof(event->mmap.filename) - size)); 288 (sizeof(event->mmap.filename) - size));
@@ -284,11 +294,14 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
284 294
285 memcpy(event->mmap.filename, pos->dso->long_name, 295 memcpy(event->mmap.filename, pos->dso->long_name,
286 pos->dso->long_name_len + 1); 296 pos->dso->long_name_len + 1);
287 process(tool, event, &synth_sample, machine); 297 if (process(tool, event, &synth_sample, machine) != 0) {
298 rc = -1;
299 break;
300 }
288 } 301 }
289 302
290 free(event); 303 free(event);
291 return 0; 304 return rc;
292} 305}
293 306
294static int __event__synthesize_thread(union perf_event *comm_event, 307static int __event__synthesize_thread(union perf_event *comm_event,
@@ -392,12 +405,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
392 if (*end) /* only interested in proper numerical dirents */ 405 if (*end) /* only interested in proper numerical dirents */
393 continue; 406 continue;
394 407
395 __event__synthesize_thread(comm_event, mmap_event, pid, 1, 408 if (__event__synthesize_thread(comm_event, mmap_event, pid, 1,
396 process, tool, machine); 409 process, tool, machine) != 0) {
410 err = -1;
411 goto out_closedir;
412 }
397 } 413 }
398 414
399 closedir(proc);
400 err = 0; 415 err = 0;
416out_closedir:
417 closedir(proc);
401out_free_mmap: 418out_free_mmap:
402 free(mmap_event); 419 free(mmap_event);
403out_free_comm: 420out_free_comm:
@@ -412,7 +429,7 @@ struct process_symbol_args {
412}; 429};
413 430
414static int find_symbol_cb(void *arg, const char *name, char type, 431static int find_symbol_cb(void *arg, const char *name, char type,
415 u64 start, u64 end __used) 432 u64 start)
416{ 433{
417 struct process_symbol_args *args = arg; 434 struct process_symbol_args *args = arg;
418 435
@@ -477,7 +494,7 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
477 map = machine->vmlinux_maps[MAP__FUNCTION]; 494 map = machine->vmlinux_maps[MAP__FUNCTION];
478 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), 495 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
479 "%s%s", mmap_name, symbol_name) + 1; 496 "%s%s", mmap_name, symbol_name) + 1;
480 size = ALIGN(size, sizeof(u64)); 497 size = PERF_ALIGN(size, sizeof(u64));
481 event->mmap.header.type = PERF_RECORD_MMAP; 498 event->mmap.header.type = PERF_RECORD_MMAP;
482 event->mmap.header.size = (sizeof(event->mmap) - 499 event->mmap.header.size = (sizeof(event->mmap) -
483 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); 500 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
@@ -497,9 +514,9 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
497 return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid); 514 return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid);
498} 515}
499 516
500int perf_event__process_comm(struct perf_tool *tool __used, 517int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
501 union perf_event *event, 518 union perf_event *event,
502 struct perf_sample *sample __used, 519 struct perf_sample *sample __maybe_unused,
503 struct machine *machine) 520 struct machine *machine)
504{ 521{
505 struct thread *thread = machine__findnew_thread(machine, event->comm.tid); 522 struct thread *thread = machine__findnew_thread(machine, event->comm.tid);
@@ -515,10 +532,10 @@ int perf_event__process_comm(struct perf_tool *tool __used,
515 return 0; 532 return 0;
516} 533}
517 534
518int perf_event__process_lost(struct perf_tool *tool __used, 535int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
519 union perf_event *event, 536 union perf_event *event,
520 struct perf_sample *sample __used, 537 struct perf_sample *sample __maybe_unused,
521 struct machine *machine __used) 538 struct machine *machine __maybe_unused)
522{ 539{
523 dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", 540 dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
524 event->lost.id, event->lost.lost); 541 event->lost.id, event->lost.lost);
@@ -538,7 +555,8 @@ static void perf_event__set_kernel_mmap_len(union perf_event *event,
538 maps[MAP__FUNCTION]->end = ~0ULL; 555 maps[MAP__FUNCTION]->end = ~0ULL;
539} 556}
540 557
541static int perf_event__process_kernel_mmap(struct perf_tool *tool __used, 558static int perf_event__process_kernel_mmap(struct perf_tool *tool
559 __maybe_unused,
542 union perf_event *event, 560 union perf_event *event,
543 struct machine *machine) 561 struct machine *machine)
544{ 562{
@@ -640,7 +658,7 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
640 658
641int perf_event__process_mmap(struct perf_tool *tool, 659int perf_event__process_mmap(struct perf_tool *tool,
642 union perf_event *event, 660 union perf_event *event,
643 struct perf_sample *sample __used, 661 struct perf_sample *sample __maybe_unused,
644 struct machine *machine) 662 struct machine *machine)
645{ 663{
646 struct thread *thread; 664 struct thread *thread;
@@ -684,9 +702,9 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
684 event->fork.ppid, event->fork.ptid); 702 event->fork.ppid, event->fork.ptid);
685} 703}
686 704
687int perf_event__process_task(struct perf_tool *tool __used, 705int perf_event__process_task(struct perf_tool *tool __maybe_unused,
688 union perf_event *event, 706 union perf_event *event,
689 struct perf_sample *sample __used, 707 struct perf_sample *sample __maybe_unused,
690 struct machine *machine) 708 struct machine *machine)
691{ 709{
692 struct thread *thread = machine__findnew_thread(machine, event->fork.tid); 710 struct thread *thread = machine__findnew_thread(machine, event->fork.tid);
@@ -886,8 +904,9 @@ int perf_event__preprocess_sample(const union perf_event *event,
886 al->sym = map__find_symbol(al->map, al->addr, filter); 904 al->sym = map__find_symbol(al->map, al->addr, filter);
887 } 905 }
888 906
889 if (symbol_conf.sym_list && al->sym && 907 if (symbol_conf.sym_list &&
890 !strlist__has_entry(symbol_conf.sym_list, al->sym->name)) 908 (!al->sym || !strlist__has_entry(symbol_conf.sym_list,
909 al->sym->name)))
891 goto out_filtered; 910 goto out_filtered;
892 911
893 return 0; 912 return 0;