aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 20:06:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 20:06:34 -0500
commitad5d69899e52792671c1aa6c7360464c7edfe09c (patch)
tree21833c1fdab4b3cf791d4fdc86dd578e4a620514 /tools/perf/builtin-script.c
parentef1417a5a6a400dbc1a2f44da716ab146a29ddc4 (diff)
parentcaea6cf52139116e43e615d87fcbf9823e197fdf (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "As a first remark I'd like to note that the way to build perf tooling has been simplified and sped up, in the future it should be enough for you to build perf via: cd tools/perf/ make install (ie without the -j option.) The build system will figure out the number of CPUs and will do a parallel build+install. The various build system inefficiencies and breakages Linus reported against the v3.12 pull request should now be resolved - please (re-)report any remaining annoyances or bugs. Main changes on the perf kernel side: * Performance optimizations: . perf ring-buffer code optimizations, by Peter Zijlstra . perf ring-buffer code optimizations, by Oleg Nesterov . x86 NMI call-stack processing optimizations, by Peter Zijlstra . perf context-switch optimizations, by Peter Zijlstra . perf sampling speedups, by Peter Zijlstra . x86 Intel PEBS processing speedups, by Peter Zijlstra * Enhanced hardware support: . for Intel Ivy Bridge-EP uncore PMUs, by Zheng Yan . for Haswell transactions, by Andi Kleen, Peter Zijlstra * Core perf events code enhancements and fixes by Oleg Nesterov: . for uprobes, if fork() is called with pending ret-probes . for uprobes platform support code * New ABI details by Andi Kleen: . Report x86 Haswell TSX transaction abort cost as weight Main changes on the perf tooling side (some of these tooling changes utilize the above kernel side changes): * 'perf report/top' enhancements: . Convert callchain children list to rbtree, greatly reducing the time taken for callchain processing, from Namhyung Kim. . Add new COMM infrastructure, further improving histogram processing, from Frédéric Weisbecker, one fix from Namhyung Kim. . Add /proc/kcore based live-annotation improvements, including build-id cache support, multi map 'call' instruction navigation fixes, kcore address validation, objdump workarounds. From Adrian Hunter. . Show progress on histogram collapsing, that can take a long time, from Namhyung Kim. . Add --max-stack option to limit callchain stack scan in 'top' and 'report', improving callchain processing when reducing the stack depth is an option, from Waiman Long. . Add new option --ignore-vmlinux for perf top, from Willy Tarreau. * 'perf trace' enhancements: . 'perf trace' now can can use a 'perf probe' dynamic tracepoints to hook into the userspace -> kernel pathname copy so that it can map fds to pathnames without reading /proc/pid/fd/ symlinks. From Arnaldo Carvalho de Melo. . Show VFS path associated with fd in live sessions, using a 'vfs_getname' 'perf probe' created dynamic tracepoint or by looking at /proc/pid/fd, from Arnaldo Carvalho de Melo. . Add 'trace' beautifiers for lots of syscall arguments, from Arnaldo Carvalho de Melo. . Implement more compact 'trace' output by suppressing zeroed args, from Arnaldo Carvalho de Melo. . Show thread COMM by default in 'trace', from Arnaldo Carvalho de Melo. . Add option to show full timestamp in 'trace', from David Ahern. . Add 'record' command in 'trace', to record raw_syscalls:*, from David Ahern. . Add summary option to dump syscall statistics in 'trace', from David Ahern. . Improve error messages in 'trace', providing hints about system configuration steps needed for using it, from Ramkumar Ramachandra. . 'perf trace' now emits hints as to why tracing is not possible, helping the user to setup the system to allow tracing in the desired permission granularity, telling if the problem is due to debugfs not being mounted or with not enough permission for !root, /proc/sys/kernel/perf_event_paranoit value, etc. From Arnaldo Carvalho de Melo. * 'perf record' enhancements: . Check maximum frequency rate for record/top, emitting better error messages, from Jiri Olsa. . 'perf record' code cleanups, from David Ahern. . Improve write_output error message in 'perf record', from Adrian Hunter. . Allow specifying B/K/M/G unit to the --mmap-pages arguments, from Jiri Olsa. . Fix command line callchain attribute tests to handle the new -g/--call-chain semantics, from Arnaldo Carvalho de Melo. * 'perf kvm' enhancements: . Disable live kvm command if timerfd is not supported, from David Ahern. . Fix detection of non-core features, from David Ahern. * 'perf list' enhancements: . Add usage to 'perf list', from David Ahern. . Show error in 'perf list' if tracepoints not available, from Pekka Enberg. * 'perf probe' enhancements: . Support "$vars" meta argument syntax for local variables, allowing asking for all possible variables at a given probe point to be collected when it hits, from Masami Hiramatsu. * 'perf sched' enhancements: . Address the root cause of that 'perf sched' stack initialization build slowdown, by programmatically setting a big array after moving the global variable back to the stack. Fix from Adrian Hunter. * 'perf script' enhancements: . Set up output options for in-stream attributes, from Adrian Hunter. . Print addr by default for BTS in 'perf script', from Adrian Juntmer * 'perf stat' enhancements: . Improved messages when doing profiling in all or a subset of CPUs using a workload as the session delimitator, as in: 'perf stat --cpu 0,2 sleep 10s' from Arnaldo Carvalho de Melo. . Add units to nanosec-based counters in 'perf stat', from David Ahern. . Remove bogus info when using 'perf stat' -e cycles/instructions, from Ramkumar Ramachandra. * 'perf lock' enhancements: . 'perf lock' fixes and cleanups, from Davidlohr Bueso. * 'perf test' enhancements: . Fixup PERF_SAMPLE_TRANSACTION handling in sample synthesizing and 'perf test', from Adrian Hunter. . Clarify the "sample parsing" test entry, from Arnaldo Carvalho de Melo. . Consider PERF_SAMPLE_TRANSACTION in the "sample parsing" test, from Arnaldo Carvalho de Melo. . Memory leak fixes in 'perf test', from Felipe Pena. * 'perf bench' enhancements: . Change the procps visible command-name of invididual benchmark tests plus cleanups, from Ingo Molnar. * Generic perf tooling infrastructure/plumbing changes: . Separating data file properties from session, code reorganization from Jiri Olsa. . Fix version when building out of tree, as when using one of these: $ make help | grep perf perf-tar-src-pkg - Build perf-3.12.0.tar source tarball perf-targz-src-pkg - Build perf-3.12.0.tar.gz source tarball perf-tarbz2-src-pkg - Build perf-3.12.0.tar.bz2 source tarball perf-tarxz-src-pkg - Build perf-3.12.0.tar.xz source tarball $ from David Ahern. . Enhance option parse error message, showing just the help lines of the options affected, from Namhyung Kim. . libtraceevent updates from upstream trace-cmd repo, from Steven Rostedt. . Always use perf_evsel__set_sample_bit to set sample_type, from Adrian Hunter. . Memory and mmap leak fixes from Chenggang Qin. . Assorted build fixes for from David Ahern and Jiri Olsa. . Speed up and prettify the build system, from Ingo Molnar. . Implement addr2line directly using libbfd, from Roberto Vitillo. . Separate the GTK support in a separate libperf-gtk.so DSO, that is only loaded when --gtk is specified, from Namhyung Kim. . perf bash completion fixes and improvements from Ramkumar Ramachandra. . Support for Openembedded/Yocto -dbg packages, from Ricardo Ribalda Delgado. And lots and lots of other fixes and code reorganizations that did not make it into the list, see the shortlog, diffstat and the Git log for details!" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (300 commits) uprobes: Fix the memory out of bound overwrite in copy_insn() uprobes: Fix the wrong usage of current->utask in uprobe_copy_process() perf tools: Remove unneeded include perf record: Remove post_processing_offset variable perf record: Remove advance_output function perf record: Refactor feature handling into a separate function perf trace: Don't relookup fields by name in each sample perf tools: Fix version when building out of tree perf evsel: Ditch evsel->handler.data field uprobes: Export write_opcode() as uprobe_write_opcode() uprobes: Introduce arch_uprobe->ixol uprobes: Kill module_init() and module_exit() uprobes: Move function declarations out of arch perf/x86/intel: Add Ivy Bridge-EP uncore IRP box support perf/x86/intel/uncore: Add filter support for IvyBridge-EP QPI boxes perf: Factor out strncpy() in perf_event_mmap_event() tools/perf: Add required memory barriers perf: Fix arch_perf_out_copy_user default perf: Update a stale comment perf: Optimize perf_output_begin() -- address calculation ...
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c127
1 files changed, 89 insertions, 38 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 9c333ff3dfeb..baf17989a216 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -15,6 +15,7 @@
15#include "util/evlist.h" 15#include "util/evlist.h"
16#include "util/evsel.h" 16#include "util/evsel.h"
17#include "util/sort.h" 17#include "util/sort.h"
18#include "util/data.h"
18#include <linux/bitmap.h> 19#include <linux/bitmap.h>
19 20
20static char const *script_name; 21static char const *script_name;
@@ -228,6 +229,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
228 return 0; 229 return 0;
229} 230}
230 231
232static void set_print_ip_opts(struct perf_event_attr *attr)
233{
234 unsigned int type = attr->type;
235
236 output[type].print_ip_opts = 0;
237 if (PRINT_FIELD(IP))
238 output[type].print_ip_opts |= PRINT_IP_OPT_IP;
239
240 if (PRINT_FIELD(SYM))
241 output[type].print_ip_opts |= PRINT_IP_OPT_SYM;
242
243 if (PRINT_FIELD(DSO))
244 output[type].print_ip_opts |= PRINT_IP_OPT_DSO;
245
246 if (PRINT_FIELD(SYMOFFSET))
247 output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
248}
249
231/* 250/*
232 * verify all user requested events exist and the samples 251 * verify all user requested events exist and the samples
233 * have the expected data 252 * have the expected data
@@ -236,7 +255,6 @@ static int perf_session__check_output_opt(struct perf_session *session)
236{ 255{
237 int j; 256 int j;
238 struct perf_evsel *evsel; 257 struct perf_evsel *evsel;
239 struct perf_event_attr *attr;
240 258
241 for (j = 0; j < PERF_TYPE_MAX; ++j) { 259 for (j = 0; j < PERF_TYPE_MAX; ++j) {
242 evsel = perf_session__find_first_evtype(session, j); 260 evsel = perf_session__find_first_evtype(session, j);
@@ -259,20 +277,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
259 if (evsel == NULL) 277 if (evsel == NULL)
260 continue; 278 continue;
261 279
262 attr = &evsel->attr; 280 set_print_ip_opts(&evsel->attr);
263
264 output[j].print_ip_opts = 0;
265 if (PRINT_FIELD(IP))
266 output[j].print_ip_opts |= PRINT_IP_OPT_IP;
267
268 if (PRINT_FIELD(SYM))
269 output[j].print_ip_opts |= PRINT_IP_OPT_SYM;
270
271 if (PRINT_FIELD(DSO))
272 output[j].print_ip_opts |= PRINT_IP_OPT_DSO;
273
274 if (PRINT_FIELD(SYMOFFSET))
275 output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
276 } 281 }
277 282
278 return 0; 283 return 0;
@@ -290,11 +295,11 @@ static void print_sample_start(struct perf_sample *sample,
290 295
291 if (PRINT_FIELD(COMM)) { 296 if (PRINT_FIELD(COMM)) {
292 if (latency_format) 297 if (latency_format)
293 printf("%8.8s ", thread->comm); 298 printf("%8.8s ", thread__comm_str(thread));
294 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) 299 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
295 printf("%s ", thread->comm); 300 printf("%s ", thread__comm_str(thread));
296 else 301 else
297 printf("%16s ", thread->comm); 302 printf("%16s ", thread__comm_str(thread));
298 } 303 }
299 304
300 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 305 if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
@@ -409,7 +414,9 @@ static void print_sample_bts(union perf_event *event,
409 printf(" => "); 414 printf(" => ");
410 415
411 /* print branch_to information */ 416 /* print branch_to information */
412 if (PRINT_FIELD(ADDR)) 417 if (PRINT_FIELD(ADDR) ||
418 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
419 !output[attr->type].user_set))
413 print_sample_addr(event, sample, machine, thread, attr); 420 print_sample_addr(event, sample, machine, thread, attr);
414 421
415 printf("\n"); 422 printf("\n");
@@ -539,32 +546,51 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
539 return 0; 546 return 0;
540} 547}
541 548
542static struct perf_tool perf_script = { 549struct perf_script {
543 .sample = process_sample_event, 550 struct perf_tool tool;
544 .mmap = perf_event__process_mmap, 551 struct perf_session *session;
545 .mmap2 = perf_event__process_mmap2,
546 .comm = perf_event__process_comm,
547 .exit = perf_event__process_exit,
548 .fork = perf_event__process_fork,
549 .attr = perf_event__process_attr,
550 .tracing_data = perf_event__process_tracing_data,
551 .build_id = perf_event__process_build_id,
552 .ordered_samples = true,
553 .ordering_requires_timestamps = true,
554}; 552};
555 553
554static int process_attr(struct perf_tool *tool, union perf_event *event,
555 struct perf_evlist **pevlist)
556{
557 struct perf_script *scr = container_of(tool, struct perf_script, tool);
558 struct perf_evlist *evlist;
559 struct perf_evsel *evsel, *pos;
560 int err;
561
562 err = perf_event__process_attr(tool, event, pevlist);
563 if (err)
564 return err;
565
566 evlist = *pevlist;
567 evsel = perf_evlist__last(*pevlist);
568
569 if (evsel->attr.type >= PERF_TYPE_MAX)
570 return 0;
571
572 list_for_each_entry(pos, &evlist->entries, node) {
573 if (pos->attr.type == evsel->attr.type && pos != evsel)
574 return 0;
575 }
576
577 set_print_ip_opts(&evsel->attr);
578
579 return perf_evsel__check_attr(evsel, scr->session);
580}
581
556static void sig_handler(int sig __maybe_unused) 582static void sig_handler(int sig __maybe_unused)
557{ 583{
558 session_done = 1; 584 session_done = 1;
559} 585}
560 586
561static int __cmd_script(struct perf_session *session) 587static int __cmd_script(struct perf_script *script)
562{ 588{
563 int ret; 589 int ret;
564 590
565 signal(SIGINT, sig_handler); 591 signal(SIGINT, sig_handler);
566 592
567 ret = perf_session__process_events(session, &perf_script); 593 ret = perf_session__process_events(script->session, &script->tool);
568 594
569 if (debug_mode) 595 if (debug_mode)
570 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 596 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -1113,10 +1139,14 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
1113 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 1139 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
1114 DIR *scripts_dir, *lang_dir; 1140 DIR *scripts_dir, *lang_dir;
1115 struct perf_session *session; 1141 struct perf_session *session;
1142 struct perf_data_file file = {
1143 .path = input_name,
1144 .mode = PERF_DATA_MODE_READ,
1145 };
1116 char *temp; 1146 char *temp;
1117 int i = 0; 1147 int i = 0;
1118 1148
1119 session = perf_session__new(input_name, O_RDONLY, 0, false, NULL); 1149 session = perf_session__new(&file, false, NULL);
1120 if (!session) 1150 if (!session)
1121 return -1; 1151 return -1;
1122 1152
@@ -1266,6 +1296,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1266 char *script_path = NULL; 1296 char *script_path = NULL;
1267 const char **__argv; 1297 const char **__argv;
1268 int i, j, err; 1298 int i, j, err;
1299 struct perf_script script = {
1300 .tool = {
1301 .sample = process_sample_event,
1302 .mmap = perf_event__process_mmap,
1303 .mmap2 = perf_event__process_mmap2,
1304 .comm = perf_event__process_comm,
1305 .exit = perf_event__process_exit,
1306 .fork = perf_event__process_fork,
1307 .attr = process_attr,
1308 .tracing_data = perf_event__process_tracing_data,
1309 .build_id = perf_event__process_build_id,
1310 .ordered_samples = true,
1311 .ordering_requires_timestamps = true,
1312 },
1313 };
1269 const struct option options[] = { 1314 const struct option options[] = {
1270 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1315 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1271 "dump raw trace in ASCII"), 1316 "dump raw trace in ASCII"),
@@ -1317,12 +1362,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1317 "perf script [<options>] <top-script> [script-args]", 1362 "perf script [<options>] <top-script> [script-args]",
1318 NULL 1363 NULL
1319 }; 1364 };
1365 struct perf_data_file file = {
1366 .mode = PERF_DATA_MODE_READ,
1367 };
1320 1368
1321 setup_scripting(); 1369 setup_scripting();
1322 1370
1323 argc = parse_options(argc, argv, options, script_usage, 1371 argc = parse_options(argc, argv, options, script_usage,
1324 PARSE_OPT_STOP_AT_NON_OPTION); 1372 PARSE_OPT_STOP_AT_NON_OPTION);
1325 1373
1374 file.path = input_name;
1375
1326 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 1376 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
1327 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 1377 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
1328 if (!rec_script_path) 1378 if (!rec_script_path)
@@ -1486,11 +1536,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1486 if (!script_name) 1536 if (!script_name)
1487 setup_pager(); 1537 setup_pager();
1488 1538
1489 session = perf_session__new(input_name, O_RDONLY, 0, false, 1539 session = perf_session__new(&file, false, &script.tool);
1490 &perf_script);
1491 if (session == NULL) 1540 if (session == NULL)
1492 return -ENOMEM; 1541 return -ENOMEM;
1493 1542
1543 script.session = session;
1544
1494 if (cpu_list) { 1545 if (cpu_list) {
1495 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1546 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1496 return -1; 1547 return -1;
@@ -1514,7 +1565,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1514 return -1; 1565 return -1;
1515 } 1566 }
1516 1567
1517 input = open(session->filename, O_RDONLY); /* input_name */ 1568 input = open(file.path, O_RDONLY); /* input_name */
1518 if (input < 0) { 1569 if (input < 0) {
1519 perror("failed to open file"); 1570 perror("failed to open file");
1520 return -1; 1571 return -1;
@@ -1554,7 +1605,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1554 if (err < 0) 1605 if (err < 0)
1555 goto out; 1606 goto out;
1556 1607
1557 err = __cmd_script(session); 1608 err = __cmd_script(&script);
1558 1609
1559 perf_session__delete(session); 1610 perf_session__delete(session);
1560 cleanup_scripting(); 1611 cleanup_scripting();