aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-options.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/util/parse-options.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/util/parse-options.c')
-rw-r--r--tools/perf/util/parse-options.c218
1 files changed, 130 insertions, 88 deletions
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 2bc9e70df7e2..31f404a032a9 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -339,10 +339,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
339 if (arg[1] != '-') { 339 if (arg[1] != '-') {
340 ctx->opt = arg + 1; 340 ctx->opt = arg + 1;
341 if (internal_help && *ctx->opt == 'h') 341 if (internal_help && *ctx->opt == 'h')
342 return parse_options_usage(usagestr, options); 342 return usage_with_options_internal(usagestr, options, 0);
343 switch (parse_short_opt(ctx, options)) { 343 switch (parse_short_opt(ctx, options)) {
344 case -1: 344 case -1:
345 return parse_options_usage(usagestr, options); 345 return parse_options_usage(usagestr, options, arg + 1, 1);
346 case -2: 346 case -2:
347 goto unknown; 347 goto unknown;
348 default: 348 default:
@@ -352,10 +352,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
352 check_typos(arg + 1, options); 352 check_typos(arg + 1, options);
353 while (ctx->opt) { 353 while (ctx->opt) {
354 if (internal_help && *ctx->opt == 'h') 354 if (internal_help && *ctx->opt == 'h')
355 return parse_options_usage(usagestr, options); 355 return usage_with_options_internal(usagestr, options, 0);
356 arg = ctx->opt;
356 switch (parse_short_opt(ctx, options)) { 357 switch (parse_short_opt(ctx, options)) {
357 case -1: 358 case -1:
358 return parse_options_usage(usagestr, options); 359 return parse_options_usage(usagestr, options, arg, 1);
359 case -2: 360 case -2:
360 /* fake a short option thing to hide the fact that we may have 361 /* fake a short option thing to hide the fact that we may have
361 * started to parse aggregated stuff 362 * started to parse aggregated stuff
@@ -383,12 +384,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
383 if (internal_help && !strcmp(arg + 2, "help-all")) 384 if (internal_help && !strcmp(arg + 2, "help-all"))
384 return usage_with_options_internal(usagestr, options, 1); 385 return usage_with_options_internal(usagestr, options, 1);
385 if (internal_help && !strcmp(arg + 2, "help")) 386 if (internal_help && !strcmp(arg + 2, "help"))
386 return parse_options_usage(usagestr, options); 387 return usage_with_options_internal(usagestr, options, 0);
387 if (!strcmp(arg + 2, "list-opts")) 388 if (!strcmp(arg + 2, "list-opts"))
388 return PARSE_OPT_LIST; 389 return PARSE_OPT_LIST;
389 switch (parse_long_opt(ctx, arg + 2, options)) { 390 switch (parse_long_opt(ctx, arg + 2, options)) {
390 case -1: 391 case -1:
391 return parse_options_usage(usagestr, options); 392 return parse_options_usage(usagestr, options, arg + 2, 0);
392 case -2: 393 case -2:
393 goto unknown; 394 goto unknown;
394 default: 395 default:
@@ -445,6 +446,89 @@ int parse_options(int argc, const char **argv, const struct option *options,
445#define USAGE_OPTS_WIDTH 24 446#define USAGE_OPTS_WIDTH 24
446#define USAGE_GAP 2 447#define USAGE_GAP 2
447 448
449static void print_option_help(const struct option *opts, int full)
450{
451 size_t pos;
452 int pad;
453
454 if (opts->type == OPTION_GROUP) {
455 fputc('\n', stderr);
456 if (*opts->help)
457 fprintf(stderr, "%s\n", opts->help);
458 return;
459 }
460 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
461 return;
462
463 pos = fprintf(stderr, " ");
464 if (opts->short_name)
465 pos += fprintf(stderr, "-%c", opts->short_name);
466 else
467 pos += fprintf(stderr, " ");
468
469 if (opts->long_name && opts->short_name)
470 pos += fprintf(stderr, ", ");
471 if (opts->long_name)
472 pos += fprintf(stderr, "--%s", opts->long_name);
473
474 switch (opts->type) {
475 case OPTION_ARGUMENT:
476 break;
477 case OPTION_LONG:
478 case OPTION_U64:
479 case OPTION_INTEGER:
480 case OPTION_UINTEGER:
481 if (opts->flags & PARSE_OPT_OPTARG)
482 if (opts->long_name)
483 pos += fprintf(stderr, "[=<n>]");
484 else
485 pos += fprintf(stderr, "[<n>]");
486 else
487 pos += fprintf(stderr, " <n>");
488 break;
489 case OPTION_CALLBACK:
490 if (opts->flags & PARSE_OPT_NOARG)
491 break;
492 /* FALLTHROUGH */
493 case OPTION_STRING:
494 if (opts->argh) {
495 if (opts->flags & PARSE_OPT_OPTARG)
496 if (opts->long_name)
497 pos += fprintf(stderr, "[=<%s>]", opts->argh);
498 else
499 pos += fprintf(stderr, "[<%s>]", opts->argh);
500 else
501 pos += fprintf(stderr, " <%s>", opts->argh);
502 } else {
503 if (opts->flags & PARSE_OPT_OPTARG)
504 if (opts->long_name)
505 pos += fprintf(stderr, "[=...]");
506 else
507 pos += fprintf(stderr, "[...]");
508 else
509 pos += fprintf(stderr, " ...");
510 }
511 break;
512 default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
513 case OPTION_END:
514 case OPTION_GROUP:
515 case OPTION_BIT:
516 case OPTION_BOOLEAN:
517 case OPTION_INCR:
518 case OPTION_SET_UINT:
519 case OPTION_SET_PTR:
520 break;
521 }
522
523 if (pos <= USAGE_OPTS_WIDTH)
524 pad = USAGE_OPTS_WIDTH - pos;
525 else {
526 fputc('\n', stderr);
527 pad = USAGE_OPTS_WIDTH;
528 }
529 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
530}
531
448int usage_with_options_internal(const char * const *usagestr, 532int usage_with_options_internal(const char * const *usagestr,
449 const struct option *opts, int full) 533 const struct option *opts, int full)
450{ 534{
@@ -464,87 +548,9 @@ int usage_with_options_internal(const char * const *usagestr,
464 if (opts->type != OPTION_GROUP) 548 if (opts->type != OPTION_GROUP)
465 fputc('\n', stderr); 549 fputc('\n', stderr);
466 550
467 for (; opts->type != OPTION_END; opts++) { 551 for ( ; opts->type != OPTION_END; opts++)
468 size_t pos; 552 print_option_help(opts, full);
469 int pad;
470
471 if (opts->type == OPTION_GROUP) {
472 fputc('\n', stderr);
473 if (*opts->help)
474 fprintf(stderr, "%s\n", opts->help);
475 continue;
476 }
477 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
478 continue;
479
480 pos = fprintf(stderr, " ");
481 if (opts->short_name)
482 pos += fprintf(stderr, "-%c", opts->short_name);
483 else
484 pos += fprintf(stderr, " ");
485
486 if (opts->long_name && opts->short_name)
487 pos += fprintf(stderr, ", ");
488 if (opts->long_name)
489 pos += fprintf(stderr, "--%s", opts->long_name);
490
491 switch (opts->type) {
492 case OPTION_ARGUMENT:
493 break;
494 case OPTION_LONG:
495 case OPTION_U64:
496 case OPTION_INTEGER:
497 case OPTION_UINTEGER:
498 if (opts->flags & PARSE_OPT_OPTARG)
499 if (opts->long_name)
500 pos += fprintf(stderr, "[=<n>]");
501 else
502 pos += fprintf(stderr, "[<n>]");
503 else
504 pos += fprintf(stderr, " <n>");
505 break;
506 case OPTION_CALLBACK:
507 if (opts->flags & PARSE_OPT_NOARG)
508 break;
509 /* FALLTHROUGH */
510 case OPTION_STRING:
511 if (opts->argh) {
512 if (opts->flags & PARSE_OPT_OPTARG)
513 if (opts->long_name)
514 pos += fprintf(stderr, "[=<%s>]", opts->argh);
515 else
516 pos += fprintf(stderr, "[<%s>]", opts->argh);
517 else
518 pos += fprintf(stderr, " <%s>", opts->argh);
519 } else {
520 if (opts->flags & PARSE_OPT_OPTARG)
521 if (opts->long_name)
522 pos += fprintf(stderr, "[=...]");
523 else
524 pos += fprintf(stderr, "[...]");
525 else
526 pos += fprintf(stderr, " ...");
527 }
528 break;
529 default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
530 case OPTION_END:
531 case OPTION_GROUP:
532 case OPTION_BIT:
533 case OPTION_BOOLEAN:
534 case OPTION_INCR:
535 case OPTION_SET_UINT:
536 case OPTION_SET_PTR:
537 break;
538 }
539 553
540 if (pos <= USAGE_OPTS_WIDTH)
541 pad = USAGE_OPTS_WIDTH - pos;
542 else {
543 fputc('\n', stderr);
544 pad = USAGE_OPTS_WIDTH;
545 }
546 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
547 }
548 fputc('\n', stderr); 554 fputc('\n', stderr);
549 555
550 return PARSE_OPT_HELP; 556 return PARSE_OPT_HELP;
@@ -559,9 +565,45 @@ void usage_with_options(const char * const *usagestr,
559} 565}
560 566
561int parse_options_usage(const char * const *usagestr, 567int parse_options_usage(const char * const *usagestr,
562 const struct option *opts) 568 const struct option *opts,
569 const char *optstr, bool short_opt)
563{ 570{
564 return usage_with_options_internal(usagestr, opts, 0); 571 if (!usagestr)
572 goto opt;
573
574 fprintf(stderr, "\n usage: %s\n", *usagestr++);
575 while (*usagestr && **usagestr)
576 fprintf(stderr, " or: %s\n", *usagestr++);
577 while (*usagestr) {
578 fprintf(stderr, "%s%s\n",
579 **usagestr ? " " : "",
580 *usagestr);
581 usagestr++;
582 }
583 fputc('\n', stderr);
584
585opt:
586 for ( ; opts->type != OPTION_END; opts++) {
587 if (short_opt) {
588 if (opts->short_name == *optstr)
589 break;
590 continue;
591 }
592
593 if (opts->long_name == NULL)
594 continue;
595
596 if (!prefixcmp(optstr, opts->long_name))
597 break;
598 if (!prefixcmp(optstr, "no-") &&
599 !prefixcmp(optstr + 3, opts->long_name))
600 break;
601 }
602
603 if (opts->type != OPTION_END)
604 print_option_help(opts, 0);
605
606 return PARSE_OPT_HELP;
565} 607}
566 608
567 609