Commit e4b546a3643fbfc510d5ef7db538e4d3ab00effb

Authored by Ingo Molnar

Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/l…

…inux-2.6 into perf/core

Showing 15 changed files Side-by-side Diff

tools/perf/Documentation/perf-annotate.txt
... ... @@ -24,12 +24,47 @@
24 24 --input=::
25 25 Input file name. (default: perf.data)
26 26  
  27 +-d::
  28 +--dsos=<dso[,dso...]>::
  29 + Only consider symbols in these dsos.
  30 +-s::
  31 +--symbol=<symbol>::
  32 + Symbol to annotate.
  33 +
  34 +-f::
  35 +--force::
  36 + Don't complain, do it.
  37 +
  38 +-v::
  39 +--verbose::
  40 + Be more verbose. (Show symbol address, etc)
  41 +
  42 +-D::
  43 +--dump-raw-trace::
  44 + Dump raw trace in ASCII.
  45 +
  46 +-k::
  47 +--vmlinux=<file>::
  48 + vmlinux pathname.
  49 +
  50 +-m::
  51 +--modules::
  52 + Load module symbols. WARNING: use only with -k and LIVE kernel.
  53 +
  54 +-l::
  55 +--print-line::
  56 + Print matching source lines (may be slow).
  57 +
  58 +-P::
  59 +--full-paths::
  60 + Don't shorten the displayed pathnames.
  61 +
27 62 --stdio:: Use the stdio interface.
28 63  
29 64 --tui:: Use the TUI interface Use of --tui requires a tty, if one is not
30 65 present, as when piping to other commands, the stdio interface is
31 66 used. This interfaces starts by centering on the line with more
32   - samples, TAB/UNTAB cycles thru the lines with more samples.
  67 + samples, TAB/UNTAB cycles through the lines with more samples.
33 68  
34 69 SEE ALSO
35 70 --------
tools/perf/Documentation/perf-buildid-list.txt
... ... @@ -18,6 +18,9 @@
18 18  
19 19 OPTIONS
20 20 -------
  21 +-H::
  22 +--with-hits::
  23 + Show only DSOs with hits.
21 24 -i::
22 25 --input=::
23 26 Input file name. (default: perf.data)
tools/perf/Documentation/perf-diff.txt
... ... @@ -19,6 +19,18 @@
19 19  
20 20 OPTIONS
21 21 -------
  22 +-M::
  23 +--displacement::
  24 + Show position displacement relative to baseline.
  25 +
  26 +-D::
  27 +--dump-raw-trace::
  28 + Dump raw trace in ASCII.
  29 +
  30 +-m::
  31 +--modules::
  32 + Load module symbols. WARNING: use only with -k and LIVE kernel
  33 +
22 34 -d::
23 35 --dsos=::
24 36 Only consider symbols in these dsos. CSV that understands
25 37  
... ... @@ -42,13 +54,18 @@
42 54 --field-separator=::
43 55  
44 56 Use a special separator character and don't pad with spaces, replacing
45   - all occurances of this separator in symbol names (and other output)
  57 + all occurrences of this separator in symbol names (and other output)
46 58 with a '.' character, that thus it's the only non valid separator.
47 59  
48 60 -v::
49 61 --verbose::
50 62 Be verbose, for instance, show the raw counts in addition to the
51 63 diff.
  64 +
  65 +-f::
  66 +--force::
  67 + Don't complain, do it.
  68 +
52 69  
53 70 SEE ALSO
54 71 --------
tools/perf/Documentation/perf-kvm.txt
... ... @@ -22,7 +22,7 @@
22 22 a performance counter profile of guest os in realtime
23 23 of an arbitrary workload.
24 24  
25   - 'perf kvm record <command>' to record the performance couinter profile
  25 + 'perf kvm record <command>' to record the performance counter profile
26 26 of an arbitrary workload and save it into a perf data file. If both
27 27 --host and --guest are input, the perf data file name is perf.data.kvm.
28 28 If there is no --host but --guest, the file name is perf.data.guest.
... ... @@ -40,6 +40,12 @@
40 40  
41 41 OPTIONS
42 42 -------
  43 +-i::
  44 +--input=::
  45 + Input file name.
  46 +-o::
  47 +--output::
  48 + Output file name.
43 49 --host=::
44 50 Collect host side performance profile.
45 51 --guest=::
tools/perf/Documentation/perf-lock.txt
... ... @@ -24,6 +24,21 @@
24 24  
25 25 'perf lock report' reports statistical data.
26 26  
  27 +OPTIONS
  28 +-------
  29 +
  30 +-i::
  31 +--input=<file>::
  32 + Input file name.
  33 +
  34 +-v::
  35 +--verbose::
  36 + Be more verbose (show symbol address, etc).
  37 +
  38 +-D::
  39 +--dump-raw-trace::
  40 + Dump raw trace in ASCII.
  41 +
27 42 SEE ALSO
28 43 --------
29 44 linkperf:perf[1]
tools/perf/Documentation/perf-probe.txt
... ... @@ -115,7 +115,7 @@
115 115  
116 116 LINE SYNTAX
117 117 -----------
118   -Line range is descripted by following syntax.
  118 +Line range is described by following syntax.
119 119  
120 120 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]"
121 121  
tools/perf/Documentation/perf-record.txt
... ... @@ -39,16 +39,25 @@
39 39 be passed as follows: '\mem:addr[:[r][w][x]]'.
40 40 If you want to profile read-write accesses in 0x1000, just set
41 41 'mem:0x1000:rw'.
  42 +
  43 +--filter=<filter>::
  44 + Event filter.
  45 +
42 46 -a::
43   - System-wide collection.
  47 +--all-cpus::
  48 + System-wide collection from all CPUs.
44 49  
45 50 -l::
46 51 Scale counter values.
47 52  
48 53 -p::
49 54 --pid=::
50   - Record events on existing pid.
  55 + Record events on existing process ID.
51 56  
  57 +-t::
  58 +--tid=::
  59 + Record events on existing thread ID.
  60 +
52 61 -r::
53 62 --realtime=::
54 63 Collect data with this RT SCHED_FIFO priority.
... ... @@ -109,8 +118,8 @@
109 118  
110 119 -C::
111 120 --cpu::
112   -Collect samples only on the list of cpus provided. Multiple CPUs can be provided as a
113   -comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
  121 +Collect samples only on the list of CPUs provided. Multiple CPUs can be provided as a
  122 +comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
114 123 In per-thread mode with inheritance mode on (default), samples are captured only when
115 124 the thread executes on the designated CPUs. Default is to monitor all CPUs.
116 125  
tools/perf/Documentation/perf-report.txt
... ... @@ -20,6 +20,11 @@
20 20 -i::
21 21 --input=::
22 22 Input file name. (default: perf.data)
  23 +
  24 +-v::
  25 +--verbose::
  26 + Be more verbose. (show symbol address, etc)
  27 +
23 28 -d::
24 29 --dsos=::
25 30 Only consider symbols in these dsos. CSV that understands
... ... @@ -27,6 +32,10 @@
27 32 -n::
28 33 --show-nr-samples::
29 34 Show the number of samples for each symbol
  35 +
  36 +--showcpuutilization::
  37 + Show sample percentage for different cpu modes.
  38 +
30 39 -T::
31 40 --threads::
32 41 Show per-thread event counters
33 42  
34 43  
... ... @@ -39,12 +48,24 @@
39 48 Only consider these symbols. CSV that understands
40 49 file://filename entries.
41 50  
  51 +-U::
  52 +--hide-unresolved::
  53 + Only display entries resolved to a symbol.
  54 +
42 55 -s::
43 56 --sort=::
44 57 Sort by key(s): pid, comm, dso, symbol, parent.
45 58  
  59 +-p::
  60 +--parent=<regex>::
  61 + regex filter to identify parent, see: '--sort parent'
  62 +
  63 +-x::
  64 +--exclude-other::
  65 + Only display entries with parent-match.
  66 +
46 67 -w::
47   ---field-width=::
  68 +--column-widths=<width[,width...]>::
48 69 Force each column width to the provided list, for large terminal
49 70 readability.
50 71  
51 72  
52 73  
53 74  
54 75  
55 76  
... ... @@ -52,25 +73,45 @@
52 73 --field-separator=::
53 74  
54 75 Use a special separator character and don't pad with spaces, replacing
55   - all occurances of this separator in symbol names (and other output)
  76 + all occurrences of this separator in symbol names (and other output)
56 77 with a '.' character, that thus it's the only non valid separator.
57 78  
  79 +-D::
  80 +--dump-raw-trace::
  81 + Dump raw trace in ASCII.
  82 +
58 83 -g [type,min]::
59 84 --call-graph::
60   - Display callchains using type and min percent threshold.
  85 + Display call chains using type and min percent threshold.
61 86 type can be either:
62   - - flat: single column, linear exposure of callchains.
  87 + - flat: single column, linear exposure of call chains.
63 88 - graph: use a graph tree, displaying absolute overhead rates.
64 89 - fractal: like graph, but displays relative rates. Each branch of
65 90 the tree is considered as a new profiled object. +
66 91 Default: fractal,0.5.
67 92  
  93 +--pretty=<key>::
  94 + Pretty printing style. key: normal, raw
  95 +
68 96 --stdio:: Use the stdio interface.
69 97  
70 98 --tui:: Use the TUI interface, that is integrated with annotate and allows
71 99 zooming into DSOs or threads, among other features. Use of --tui
72 100 requires a tty, if one is not present, as when piping to other
73 101 commands, the stdio interface is used.
  102 +
  103 +-k::
  104 +--vmlinux=<file>::
  105 + vmlinux pathname
  106 +
  107 +-m::
  108 +--modules::
  109 + Load module symbols. WARNING: This should only be used with -k and
  110 + a LIVE kernel.
  111 +
  112 +-f::
  113 +--force::
  114 + Don't complain, do it.
74 115  
75 116 SEE ALSO
76 117 --------
tools/perf/Documentation/perf-sched.txt
... ... @@ -8,11 +8,11 @@
8 8 SYNOPSIS
9 9 --------
10 10 [verse]
11   -'perf sched' {record|latency|replay|trace}
  11 +'perf sched' {record|latency|map|replay|trace}
12 12  
13 13 DESCRIPTION
14 14 -----------
15   -There are four variants of perf sched:
  15 +There are five variants of perf sched:
16 16  
17 17 'perf sched record <command>' to record the scheduling events
18 18 of an arbitrary workload.
19 19  
... ... @@ -30,8 +30,22 @@
30 30 of the workload as it occurred when it was recorded - and can repeat
31 31 it a number of times, measuring its performance.)
32 32  
  33 + 'perf sched map' to print a textual context-switching outline of
  34 + workload captured via perf sched record. Columns stand for
  35 + individual CPUs, and the two-letter shortcuts stand for tasks that
  36 + are running on a CPU. A '*' denotes the CPU that had the event, and
  37 + a dot signals an idle CPU.
  38 +
33 39 OPTIONS
34 40 -------
  41 +-i::
  42 +--input=<file>::
  43 + Input file name. (default: perf.data)
  44 +
  45 +-v::
  46 +--verbose::
  47 + Be more verbose. (show symbol address, etc)
  48 +
35 49 -D::
36 50 --dump-raw-trace=::
37 51 Display verbose dump of the sched data.
tools/perf/Documentation/perf-script.txt
... ... @@ -104,6 +104,13 @@
104 104 normally don't - this option allows the latter to be run in
105 105 system-wide mode.
106 106  
  107 +-i::
  108 +--input=::
  109 + Input file name.
  110 +
  111 +-d::
  112 +--debug-mode::
  113 + Do various checks like samples ordering and lost events.
107 114  
108 115 SEE ALSO
109 116 --------
tools/perf/Documentation/perf-stat.txt
... ... @@ -8,8 +8,8 @@
8 8 SYNOPSIS
9 9 --------
10 10 [verse]
11   -'perf stat' [-e <EVENT> | --event=EVENT] [-S] [-a] <command>
12   -'perf stat' [-e <EVENT> | --event=EVENT] [-S] [-a] -- <command> [<options>]
  11 +'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command>
  12 +'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>]
13 13  
14 14 DESCRIPTION
15 15 -----------
16 16  
17 17  
18 18  
19 19  
20 20  
21 21  
... ... @@ -35,21 +35,33 @@
35 35 child tasks do not inherit counters
36 36 -p::
37 37 --pid=<pid>::
38   - stat events on existing pid
  38 + stat events on existing process id
39 39  
  40 +-t::
  41 +--tid=<tid>::
  42 + stat events on existing thread id
  43 +
  44 +
40 45 -a::
41   - system-wide collection
  46 +--all-cpus::
  47 + system-wide collection from all CPUs
42 48  
43 49 -c::
44   - scale counter values
  50 +--scale::
  51 + scale/normalize counter values
45 52  
  53 +-r::
  54 +--repeat=<n>::
  55 + repeat command and print average + stddev (max: 100)
  56 +
46 57 -B::
  58 +--big-num::
47 59 print large numbers with thousands' separators according to locale
48 60  
49 61 -C::
50 62 --cpu=::
51   -Count only on the list of cpus provided. Multiple CPUs can be provided as a
52   -comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
  63 +Count only on the list of CPUs provided. Multiple CPUs can be provided as a
  64 +comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
53 65 In per-thread mode, this option is ignored. The -a option is still necessary
54 66 to activate system-wide monitoring. Default is to count on all CPUs.
55 67  
... ... @@ -57,6 +69,19 @@
57 69 --no-aggr::
58 70 Do not aggregate counts across all monitored CPUs in system-wide mode (-a).
59 71 This option is only valid in system-wide mode.
  72 +
  73 +-n::
  74 +--null::
  75 + null run - don't start any counters
  76 +
  77 +-v::
  78 +--verbose::
  79 + be more verbose (show counter open errors, etc)
  80 +
  81 +-x SEP::
  82 +--field-separator SEP::
  83 +print counts using a CSV-style output to make it easy to import directly into
  84 +spreadsheets. Columns are separated by the string specified in SEP.
60 85  
61 86 EXAMPLES
62 87 --------
tools/perf/Documentation/perf-test.txt
... ... @@ -12,7 +12,7 @@
12 12  
13 13 DESCRIPTION
14 14 -----------
15   -This command does assorted sanity tests, initially thru linked routines but
  15 +This command does assorted sanity tests, initially through linked routines but
16 16 also will look for a directory with more tests in the form of scripts.
17 17  
18 18 OPTIONS
tools/perf/Documentation/perf-top.txt
... ... @@ -12,7 +12,7 @@
12 12  
13 13 DESCRIPTION
14 14 -----------
15   -This command generates and displays a performance counter profile in realtime.
  15 +This command generates and displays a performance counter profile in real time.
16 16  
17 17  
18 18 OPTIONS
... ... @@ -27,8 +27,8 @@
27 27  
28 28 -C <cpu-list>::
29 29 --cpu=<cpu>::
30   -Monitor only on the list of cpus provided. Multiple CPUs can be provided as a
31   -comma-sperated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
  30 +Monitor only on the list of CPUs provided. Multiple CPUs can be provided as a
  31 +comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2.
32 32 Default is to monitor all CPUS.
33 33  
34 34 -d <seconds>::
... ... @@ -50,6 +50,10 @@
50 50 --count-filter=<count>::
51 51 Only display functions with more events than this.
52 52  
  53 +-g::
  54 +--group::
  55 + Put the counters into a counter group.
  56 +
53 57 -F <freq>::
54 58 --freq=<freq>::
55 59 Profile at this frequency.
56 60  
... ... @@ -68,8 +72,12 @@
68 72  
69 73 -p <pid>::
70 74 --pid=<pid>::
71   - Profile events on existing pid.
  75 + Profile events on existing Process ID.
72 76  
  77 +-t <tid>::
  78 +--tid=<tid>::
  79 + Profile events on existing thread ID.
  80 +
73 81 -r <priority>::
74 82 --realtime=<priority>::
75 83 Collect data with this RT SCHED_FIFO priority.
... ... @@ -77,6 +85,18 @@
77 85 -s <symbol>::
78 86 --sym-annotate=<symbol>::
79 87 Annotate this symbol.
  88 +
  89 +-K::
  90 +--hide_kernel_symbols::
  91 + Hide kernel symbols.
  92 +
  93 +-U::
  94 +--hide_user_symbols::
  95 + Hide user symbols.
  96 +
  97 +-D::
  98 +--dump-symtab::
  99 + Dump the symbol table used for profiling.
80 100  
81 101 -v::
82 102 --verbose::
tools/perf/builtin-diff.c
... ... @@ -173,7 +173,7 @@
173 173 static const struct option options[] = {
174 174 OPT_INCR('v', "verbose", &verbose,
175 175 "be more verbose (show symbol address, etc)"),
176   - OPT_BOOLEAN('m', "displacement", &show_displacement,
  176 + OPT_BOOLEAN('M', "displacement", &show_displacement,
177 177 "Show position displacement relative to baseline"),
178 178 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
179 179 "dump raw trace in ASCII"),
tools/perf/builtin-stat.c
... ... @@ -52,6 +52,8 @@
52 52 #include <math.h>
53 53 #include <locale.h>
54 54  
  55 +#define DEFAULT_SEPARATOR " "
  56 +
55 57 static struct perf_event_attr default_attrs[] = {
56 58  
57 59 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
58 60  
... ... @@ -82,8 +84,11 @@
82 84 static int thread_num = 0;
83 85 static pid_t child_pid = -1;
84 86 static bool null_run = false;
85   -static bool big_num = false;
  87 +static bool big_num = true;
  88 +static int big_num_opt = -1;
86 89 static const char *cpu_list;
  90 +static const char *csv_sep = NULL;
  91 +static bool csv_output = false;
87 92  
88 93  
89 94 static int *fd[MAX_NR_CPUS][MAX_COUNTERS];
90 95  
91 96  
... ... @@ -449,13 +454,19 @@
449 454 static void nsec_printout(int cpu, int counter, double avg)
450 455 {
451 456 double msecs = avg / 1e6;
  457 + char cpustr[16] = { '\0', };
  458 + const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-24s";
452 459  
453 460 if (no_aggr)
454   - fprintf(stderr, "CPU%-4d %18.6f %-24s",
455   - cpumap[cpu], msecs, event_name(counter));
456   - else
457   - fprintf(stderr, " %18.6f %-24s", msecs, event_name(counter));
  461 + sprintf(cpustr, "CPU%*d%s",
  462 + csv_output ? 0 : -4,
  463 + cpumap[cpu], csv_sep);
458 464  
  465 + fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(counter));
  466 +
  467 + if (csv_output)
  468 + return;
  469 +
459 470 if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) {
460 471 fprintf(stderr, " # %10.3f CPUs ",
461 472 avg / avg_stats(&walltime_nsecs_stats));
462 473  
463 474  
464 475  
465 476  
... ... @@ -466,19 +477,27 @@
466 477 {
467 478 double total, ratio = 0.0;
468 479 char cpustr[16] = { '\0', };
  480 + const char *fmt;
469 481  
  482 + if (csv_output)
  483 + fmt = "%s%.0f%s%s";
  484 + else if (big_num)
  485 + fmt = "%s%'18.0f%s%-24s";
  486 + else
  487 + fmt = "%s%18.0f%s%-24s";
  488 +
470 489 if (no_aggr)
471   - sprintf(cpustr, "CPU%-4d", cpumap[cpu]);
  490 + sprintf(cpustr, "CPU%*d%s",
  491 + csv_output ? 0 : -4,
  492 + cpumap[cpu], csv_sep);
472 493 else
473 494 cpu = 0;
474 495  
475   - if (big_num)
476   - fprintf(stderr, "%s %'18.0f %-24s",
477   - cpustr, avg, event_name(counter));
478   - else
479   - fprintf(stderr, "%s %18.0f %-24s",
480   - cpustr, avg, event_name(counter));
  496 + fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(counter));
481 497  
  498 + if (csv_output)
  499 + return;
  500 +
482 501 if (MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) {
483 502 total = avg_stats(&runtime_cycles_stats[cpu]);
484 503  
... ... @@ -515,8 +534,9 @@
515 534 int scaled = event_scaled[counter];
516 535  
517 536 if (scaled == -1) {
518   - fprintf(stderr, " %18s %-24s\n",
519   - "<not counted>", event_name(counter));
  537 + fprintf(stderr, "%*s%s%-24s\n",
  538 + csv_output ? 0 : 18,
  539 + "<not counted>", csv_sep, event_name(counter));
520 540 return;
521 541 }
522 542  
... ... @@ -525,6 +545,11 @@
525 545 else
526 546 abs_printout(-1, counter, avg);
527 547  
  548 + if (csv_output) {
  549 + fputc('\n', stderr);
  550 + return;
  551 + }
  552 +
528 553 print_noise(counter, avg);
529 554  
530 555 if (scaled) {
... ... @@ -554,8 +579,12 @@
554 579 ena = cpu_counts[cpu][counter].ena;
555 580 run = cpu_counts[cpu][counter].run;
556 581 if (run == 0 || ena == 0) {
557   - fprintf(stderr, "CPU%-4d %18s %-24s", cpumap[cpu],
558   - "<not counted>", event_name(counter));
  582 + fprintf(stderr, "CPU%*d%s%*s%s%-24s",
  583 + csv_output ? 0 : -4,
  584 + cpumap[cpu], csv_sep,
  585 + csv_output ? 0 : 18,
  586 + "<not counted>", csv_sep,
  587 + event_name(counter));
559 588  
560 589 fprintf(stderr, "\n");
561 590 continue;
562 591  
563 592  
... ... @@ -566,11 +595,13 @@
566 595 else
567 596 abs_printout(cpu, counter, val);
568 597  
569   - print_noise(counter, 1.0);
  598 + if (!csv_output) {
  599 + print_noise(counter, 1.0);
570 600  
571   - if (run != ena) {
572   - fprintf(stderr, " (scaled from %.2f%%)",
  601 + if (run != ena) {
  602 + fprintf(stderr, " (scaled from %.2f%%)",
573 603 100.0 * run / ena);
  604 + }
574 605 }
575 606 fprintf(stderr, "\n");
576 607 }
577 608  
... ... @@ -582,21 +613,23 @@
582 613  
583 614 fflush(stdout);
584 615  
585   - fprintf(stderr, "\n");
586   - fprintf(stderr, " Performance counter stats for ");
587   - if(target_pid == -1 && target_tid == -1) {
588   - fprintf(stderr, "\'%s", argv[0]);
589   - for (i = 1; i < argc; i++)
590   - fprintf(stderr, " %s", argv[i]);
591   - } else if (target_pid != -1)
592   - fprintf(stderr, "process id \'%d", target_pid);
593   - else
594   - fprintf(stderr, "thread id \'%d", target_tid);
  616 + if (!csv_output) {
  617 + fprintf(stderr, "\n");
  618 + fprintf(stderr, " Performance counter stats for ");
  619 + if(target_pid == -1 && target_tid == -1) {
  620 + fprintf(stderr, "\'%s", argv[0]);
  621 + for (i = 1; i < argc; i++)
  622 + fprintf(stderr, " %s", argv[i]);
  623 + } else if (target_pid != -1)
  624 + fprintf(stderr, "process id \'%d", target_pid);
  625 + else
  626 + fprintf(stderr, "thread id \'%d", target_tid);
595 627  
596   - fprintf(stderr, "\'");
597   - if (run_count > 1)
598   - fprintf(stderr, " (%d runs)", run_count);
599   - fprintf(stderr, ":\n\n");
  628 + fprintf(stderr, "\'");
  629 + if (run_count > 1)
  630 + fprintf(stderr, " (%d runs)", run_count);
  631 + fprintf(stderr, ":\n\n");
  632 + }
600 633  
601 634 if (no_aggr) {
602 635 for (counter = 0; counter < nr_counters; counter++)
603 636  
604 637  
... ... @@ -606,15 +639,17 @@
606 639 print_counter_aggr(counter);
607 640 }
608 641  
609   - fprintf(stderr, "\n");
610   - fprintf(stderr, " %18.9f seconds time elapsed",
611   - avg_stats(&walltime_nsecs_stats)/1e9);
612   - if (run_count > 1) {
613   - fprintf(stderr, " ( +- %7.3f%% )",
  642 + if (!csv_output) {
  643 + fprintf(stderr, "\n");
  644 + fprintf(stderr, " %18.9f seconds time elapsed",
  645 + avg_stats(&walltime_nsecs_stats)/1e9);
  646 + if (run_count > 1) {
  647 + fprintf(stderr, " ( +- %7.3f%% )",
614 648 100*stddev_stats(&walltime_nsecs_stats) /
615 649 avg_stats(&walltime_nsecs_stats));
  650 + }
  651 + fprintf(stderr, "\n\n");
616 652 }
617   - fprintf(stderr, "\n\n");
618 653 }
619 654  
620 655 static volatile int signr = -1;
... ... @@ -644,6 +679,13 @@
644 679 NULL
645 680 };
646 681  
  682 +static int stat__set_big_num(const struct option *opt __used,
  683 + const char *s __used, int unset)
  684 +{
  685 + big_num_opt = unset ? 0 : 1;
  686 + return 0;
  687 +}
  688 +
647 689 static const struct option options[] = {
648 690 OPT_CALLBACK('e', "event", NULL, "event",
649 691 "event selector. use 'perf list' to list available events",
650 692  
... ... @@ -664,12 +706,15 @@
664 706 "repeat command and print average + stddev (max: 100)"),
665 707 OPT_BOOLEAN('n', "null", &null_run,
666 708 "null run - dont start any counters"),
667   - OPT_BOOLEAN('B', "big-num", &big_num,
668   - "print large numbers with thousands\' separators"),
  709 + OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
  710 + "print large numbers with thousands\' separators",
  711 + stat__set_big_num),
669 712 OPT_STRING('C', "cpu", &cpu_list, "cpu",
670 713 "list of cpus to monitor in system-wide"),
671 714 OPT_BOOLEAN('A', "no-aggr", &no_aggr,
672 715 "disable CPU count aggregation"),
  716 + OPT_STRING('x', "field-separator", &csv_sep, "separator",
  717 + "print counts with custom separator"),
673 718 OPT_END()
674 719 };
675 720  
... ... @@ -682,6 +727,25 @@
682 727  
683 728 argc = parse_options(argc, argv, options, stat_usage,
684 729 PARSE_OPT_STOP_AT_NON_OPTION);
  730 +
  731 + if (csv_sep)
  732 + csv_output = true;
  733 + else
  734 + csv_sep = DEFAULT_SEPARATOR;
  735 +
  736 + /*
  737 + * let the spreadsheet do the pretty-printing
  738 + */
  739 + if (csv_output) {
  740 + /* User explicitely passed -B? */
  741 + if (big_num_opt == 1) {
  742 + fprintf(stderr, "-B option not supported with -x\n");
  743 + usage_with_options(stat_usage, options);
  744 + } else /* Nope, so disable big number formatting */
  745 + big_num = false;
  746 + } else if (big_num_opt == 0) /* User passed --no-big-num */
  747 + big_num = false;
  748 +
685 749 if (!argc && target_pid == -1 && target_tid == -1)
686 750 usage_with_options(stat_usage, options);
687 751 if (run_count <= 0)