aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-08-18 15:58:46 -0400
committerIngo Molnar <mingo@elte.hu>2011-08-18 15:58:46 -0400
commit51887c8230d57c4d9cc68e3784c52c8f0a708655 (patch)
tree70509225468cddacb24eccdc78c7d8fc9e0197c5 /tools
parent8bc84f87315e8bdbe242ba788fdc6a74d653b177 (diff)
parent4aa9015f8bfd2c8d7cc33a360275b71a9d708b37 (diff)
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Conflicts: tools/perf/builtin-stat.c
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt11
-rw-r--r--tools/perf/Documentation/perf-stat.txt7
-rw-r--r--tools/perf/builtin-annotate.c6
-rw-r--r--tools/perf/builtin-stat.c155
-rw-r--r--tools/perf/util/annotate.c5
-rw-r--r--tools/perf/util/color.c2
-rw-r--r--tools/perf/util/symbol.c2
-rw-r--r--tools/perf/util/symbol.h4
8 files changed, 126 insertions, 66 deletions
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 85c5f026930d..98a31e3181a5 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -72,6 +72,17 @@ OPTIONS
72 CPUs are specified with -: 0-2. Default is to report samples on all 72 CPUs are specified with -: 0-2. Default is to report samples on all
73 CPUs. 73 CPUs.
74 74
75--asm-raw::
76 Show raw instruction encoding of assembly instructions. They
77 are displayed by default, disable with --no-asm-raw.
78
79--source::
80 Interleave source code with assembly code. Enabled by default,
81 disable with --no-source.
82
83--symfs=<directory>::
84 Look for files with symbols relative to this directory.
85
75SEE ALSO 86SEE ALSO
76-------- 87--------
77linkperf:perf-record[1], linkperf:perf-report[1] 88linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 918cc38ee6d1..08394c4879a8 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -94,6 +94,13 @@ an empty cgroup (monitor all the time) using, e.g., -G foo,,bar. Cgroups must ha
94corresponding events, i.e., they always refer to events defined earlier on the command 94corresponding events, i.e., they always refer to events defined earlier on the command
95line. 95line.
96 96
97-o file::
98-output file::
99Print the output into the designated file.
100
101--append::
102Append to the output file designated with the -o option. Ignored if -o is not specified.
103
97EXAMPLES 104EXAMPLES
98-------- 105--------
99 106
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 555aefd7fe01..c5be28851f01 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -267,6 +267,12 @@ static const struct option options[] = {
267 OPT_BOOLEAN('P', "full-paths", &full_paths, 267 OPT_BOOLEAN('P', "full-paths", &full_paths,
268 "Don't shorten the displayed pathnames"), 268 "Don't shorten the displayed pathnames"),
269 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 269 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
270 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
271 "Look for files with symbols relative to this directory"),
272 OPT_BOOLEAN('0', "source", &symbol_conf.annotate_src,
273 "Interleave source code with assembly code (default)"),
274 OPT_BOOLEAN('0', "asm-raw", &symbol_conf.annotate_asm_raw,
275 "Display raw encoding of assembly instructions (default)"),
270 OPT_END() 276 OPT_END()
271}; 277};
272 278
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5deb17d9e795..bec64a9e741c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -194,6 +194,8 @@ static const char *cpu_list;
194static const char *csv_sep = NULL; 194static const char *csv_sep = NULL;
195static bool csv_output = false; 195static bool csv_output = false;
196static bool group = false; 196static bool group = false;
197static const char *output_name = NULL;
198static FILE *output = NULL;
197 199
198static volatile int done = 0; 200static volatile int done = 0;
199 201
@@ -352,7 +354,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
352 update_stats(&ps->res_stats[i], count[i]); 354 update_stats(&ps->res_stats[i], count[i]);
353 355
354 if (verbose) { 356 if (verbose) {
355 fprintf(stderr, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 357 fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
356 event_name(counter), count[0], count[1], count[2]); 358 event_name(counter), count[0], count[1], count[2]);
357 } 359 }
358 360
@@ -519,9 +521,9 @@ static void print_noise_pct(double total, double avg)
519 pct = 100.0*total/avg; 521 pct = 100.0*total/avg;
520 522
521 if (csv_output) 523 if (csv_output)
522 fprintf(stderr, "%s%.2f%%", csv_sep, pct); 524 fprintf(output, "%s%.2f%%", csv_sep, pct);
523 else 525 else
524 fprintf(stderr, " ( +-%6.2f%% )", pct); 526 fprintf(output, " ( +-%6.2f%% )", pct);
525} 527}
526 528
527static void print_noise(struct perf_evsel *evsel, double avg) 529static void print_noise(struct perf_evsel *evsel, double avg)
@@ -546,16 +548,17 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
546 csv_output ? 0 : -4, 548 csv_output ? 0 : -4,
547 evsel_list->cpus->map[cpu], csv_sep); 549 evsel_list->cpus->map[cpu], csv_sep);
548 550
549 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel)); 551 fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel));
550 552
551 if (evsel->cgrp) 553 if (evsel->cgrp)
552 fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name); 554 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
553 555
554 if (csv_output) 556 if (csv_output)
555 return; 557 return;
556 558
557 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 559 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
558 fprintf(stderr, " # %8.3f CPUs utilized ", avg / avg_stats(&walltime_nsecs_stats)); 560 fprintf(output, " # %8.3f CPUs utilized ",
561 avg / avg_stats(&walltime_nsecs_stats));
559} 562}
560 563
561static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg) 564static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -576,9 +579,9 @@ static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __us
576 else if (ratio > 10.0) 579 else if (ratio > 10.0)
577 color = PERF_COLOR_YELLOW; 580 color = PERF_COLOR_YELLOW;
578 581
579 fprintf(stderr, " # "); 582 fprintf(output, " # ");
580 color_fprintf(stderr, color, "%6.2f%%", ratio); 583 color_fprintf(output, color, "%6.2f%%", ratio);
581 fprintf(stderr, " frontend cycles idle "); 584 fprintf(output, " frontend cycles idle ");
582} 585}
583 586
584static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg) 587static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -599,9 +602,9 @@ static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __use
599 else if (ratio > 20.0) 602 else if (ratio > 20.0)
600 color = PERF_COLOR_YELLOW; 603 color = PERF_COLOR_YELLOW;
601 604
602 fprintf(stderr, " # "); 605 fprintf(output, " # ");
603 color_fprintf(stderr, color, "%6.2f%%", ratio); 606 color_fprintf(output, color, "%6.2f%%", ratio);
604 fprintf(stderr, " backend cycles idle "); 607 fprintf(output, " backend cycles idle ");
605} 608}
606 609
607static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg) 610static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -622,9 +625,9 @@ static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double
622 else if (ratio > 5.0) 625 else if (ratio > 5.0)
623 color = PERF_COLOR_YELLOW; 626 color = PERF_COLOR_YELLOW;
624 627
625 fprintf(stderr, " # "); 628 fprintf(output, " # ");
626 color_fprintf(stderr, color, "%6.2f%%", ratio); 629 color_fprintf(output, color, "%6.2f%%", ratio);
627 fprintf(stderr, " of all branches "); 630 fprintf(output, " of all branches ");
628} 631}
629 632
630static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 633static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -645,9 +648,9 @@ static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, dou
645 else if (ratio > 5.0) 648 else if (ratio > 5.0)
646 color = PERF_COLOR_YELLOW; 649 color = PERF_COLOR_YELLOW;
647 650
648 fprintf(stderr, " # "); 651 fprintf(output, " # ");
649 color_fprintf(stderr, color, "%6.2f%%", ratio); 652 color_fprintf(output, color, "%6.2f%%", ratio);
650 fprintf(stderr, " of all L1-dcache hits "); 653 fprintf(output, " of all L1-dcache hits ");
651} 654}
652 655
653static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 656static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -668,9 +671,9 @@ static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, dou
668 else if (ratio > 5.0) 671 else if (ratio > 5.0)
669 color = PERF_COLOR_YELLOW; 672 color = PERF_COLOR_YELLOW;
670 673
671 fprintf(stderr, " # "); 674 fprintf(output, " # ");
672 color_fprintf(stderr, color, "%6.2f%%", ratio); 675 color_fprintf(output, color, "%6.2f%%", ratio);
673 fprintf(stderr, " of all L1-icache hits "); 676 fprintf(output, " of all L1-icache hits ");
674} 677}
675 678
676static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 679static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -691,9 +694,9 @@ static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, do
691 else if (ratio > 5.0) 694 else if (ratio > 5.0)
692 color = PERF_COLOR_YELLOW; 695 color = PERF_COLOR_YELLOW;
693 696
694 fprintf(stderr, " # "); 697 fprintf(output, " # ");
695 color_fprintf(stderr, color, "%6.2f%%", ratio); 698 color_fprintf(output, color, "%6.2f%%", ratio);
696 fprintf(stderr, " of all dTLB cache hits "); 699 fprintf(output, " of all dTLB cache hits ");
697} 700}
698 701
699static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 702static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -714,9 +717,9 @@ static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, do
714 else if (ratio > 5.0) 717 else if (ratio > 5.0)
715 color = PERF_COLOR_YELLOW; 718 color = PERF_COLOR_YELLOW;
716 719
717 fprintf(stderr, " # "); 720 fprintf(output, " # ");
718 color_fprintf(stderr, color, "%6.2f%%", ratio); 721 color_fprintf(output, color, "%6.2f%%", ratio);
719 fprintf(stderr, " of all iTLB cache hits "); 722 fprintf(output, " of all iTLB cache hits ");
720} 723}
721 724
722static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 725static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -737,9 +740,9 @@ static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, doub
737 else if (ratio > 5.0) 740 else if (ratio > 5.0)
738 color = PERF_COLOR_YELLOW; 741 color = PERF_COLOR_YELLOW;
739 742
740 fprintf(stderr, " # "); 743 fprintf(output, " # ");
741 color_fprintf(stderr, color, "%6.2f%%", ratio); 744 color_fprintf(output, color, "%6.2f%%", ratio);
742 fprintf(stderr, " of all LL-cache hits "); 745 fprintf(output, " of all LL-cache hits ");
743} 746}
744 747
745static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) 748static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
@@ -762,10 +765,10 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
762 else 765 else
763 cpu = 0; 766 cpu = 0;
764 767
765 fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(evsel)); 768 fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel));
766 769
767 if (evsel->cgrp) 770 if (evsel->cgrp)
768 fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name); 771 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
769 772
770 if (csv_output) 773 if (csv_output)
771 return; 774 return;
@@ -776,14 +779,14 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
776 if (total) 779 if (total)
777 ratio = avg / total; 780 ratio = avg / total;
778 781
779 fprintf(stderr, " # %5.2f insns per cycle ", ratio); 782 fprintf(output, " # %5.2f insns per cycle ", ratio);
780 783
781 total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 784 total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
782 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 785 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
783 786
784 if (total && avg) { 787 if (total && avg) {
785 ratio = total / avg; 788 ratio = total / avg;
786 fprintf(stderr, "\n # %5.2f stalled cycles per insn", ratio); 789 fprintf(output, "\n # %5.2f stalled cycles per insn", ratio);
787 } 790 }
788 791
789 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 792 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
@@ -831,7 +834,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
831 if (total) 834 if (total)
832 ratio = avg * 100 / total; 835 ratio = avg * 100 / total;
833 836
834 fprintf(stderr, " # %8.3f %% of all cache refs ", ratio); 837 fprintf(output, " # %8.3f %% of all cache refs ", ratio);
835 838
836 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 839 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
837 print_stalled_cycles_frontend(cpu, evsel, avg); 840 print_stalled_cycles_frontend(cpu, evsel, avg);
@@ -843,16 +846,16 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
843 if (total) 846 if (total)
844 ratio = 1.0 * avg / total; 847 ratio = 1.0 * avg / total;
845 848
846 fprintf(stderr, " # %8.3f GHz ", ratio); 849 fprintf(output, " # %8.3f GHz ", ratio);
847 } else if (runtime_nsecs_stats[cpu].n != 0) { 850 } else if (runtime_nsecs_stats[cpu].n != 0) {
848 total = avg_stats(&runtime_nsecs_stats[cpu]); 851 total = avg_stats(&runtime_nsecs_stats[cpu]);
849 852
850 if (total) 853 if (total)
851 ratio = 1000.0 * avg / total; 854 ratio = 1000.0 * avg / total;
852 855
853 fprintf(stderr, " # %8.3f M/sec ", ratio); 856 fprintf(output, " # %8.3f M/sec ", ratio);
854 } else { 857 } else {
855 fprintf(stderr, " "); 858 fprintf(output, " ");
856 } 859 }
857} 860}
858 861
@@ -867,7 +870,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
867 int scaled = counter->counts->scaled; 870 int scaled = counter->counts->scaled;
868 871
869 if (scaled == -1) { 872 if (scaled == -1) {
870 fprintf(stderr, "%*s%s%*s", 873 fprintf(output, "%*s%s%*s",
871 csv_output ? 0 : 18, 874 csv_output ? 0 : 18,
872 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 875 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
873 csv_sep, 876 csv_sep,
@@ -875,9 +878,9 @@ static void print_counter_aggr(struct perf_evsel *counter)
875 event_name(counter)); 878 event_name(counter));
876 879
877 if (counter->cgrp) 880 if (counter->cgrp)
878 fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name); 881 fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
879 882
880 fputc('\n', stderr); 883 fputc('\n', output);
881 return; 884 return;
882 } 885 }
883 886
@@ -889,7 +892,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
889 print_noise(counter, avg); 892 print_noise(counter, avg);
890 893
891 if (csv_output) { 894 if (csv_output) {
892 fputc('\n', stderr); 895 fputc('\n', output);
893 return; 896 return;
894 } 897 }
895 898
@@ -899,9 +902,9 @@ static void print_counter_aggr(struct perf_evsel *counter)
899 avg_enabled = avg_stats(&ps->res_stats[1]); 902 avg_enabled = avg_stats(&ps->res_stats[1]);
900 avg_running = avg_stats(&ps->res_stats[2]); 903 avg_running = avg_stats(&ps->res_stats[2]);
901 904
902 fprintf(stderr, " [%5.2f%%]", 100 * avg_running / avg_enabled); 905 fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled);
903 } 906 }
904 fprintf(stderr, "\n"); 907 fprintf(output, "\n");
905} 908}
906 909
907/* 910/*
@@ -918,7 +921,7 @@ static void print_counter(struct perf_evsel *counter)
918 ena = counter->counts->cpu[cpu].ena; 921 ena = counter->counts->cpu[cpu].ena;
919 run = counter->counts->cpu[cpu].run; 922 run = counter->counts->cpu[cpu].run;
920 if (run == 0 || ena == 0) { 923 if (run == 0 || ena == 0) {
921 fprintf(stderr, "CPU%*d%s%*s%s%*s", 924 fprintf(output, "CPU%*d%s%*s%s%*s",
922 csv_output ? 0 : -4, 925 csv_output ? 0 : -4,
923 evsel_list->cpus->map[cpu], csv_sep, 926 evsel_list->cpus->map[cpu], csv_sep,
924 csv_output ? 0 : 18, 927 csv_output ? 0 : 18,
@@ -928,9 +931,10 @@ static void print_counter(struct perf_evsel *counter)
928 event_name(counter)); 931 event_name(counter));
929 932
930 if (counter->cgrp) 933 if (counter->cgrp)
931 fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name); 934 fprintf(output, "%s%s",
935 csv_sep, counter->cgrp->name);
932 936
933 fputc('\n', stderr); 937 fputc('\n', output);
934 continue; 938 continue;
935 } 939 }
936 940
@@ -943,9 +947,10 @@ static void print_counter(struct perf_evsel *counter)
943 print_noise(counter, 1.0); 947 print_noise(counter, 1.0);
944 948
945 if (run != ena) 949 if (run != ena)
946 fprintf(stderr, " (%.2f%%)", 100.0 * run / ena); 950 fprintf(output, " (%.2f%%)",
951 100.0 * run / ena);
947 } 952 }
948 fputc('\n', stderr); 953 fputc('\n', output);
949 } 954 }
950} 955}
951 956
@@ -957,21 +962,21 @@ static void print_stat(int argc, const char **argv)
957 fflush(stdout); 962 fflush(stdout);
958 963
959 if (!csv_output) { 964 if (!csv_output) {
960 fprintf(stderr, "\n"); 965 fprintf(output, "\n");
961 fprintf(stderr, " Performance counter stats for "); 966 fprintf(output, " Performance counter stats for ");
962 if(target_pid == -1 && target_tid == -1) { 967 if(target_pid == -1 && target_tid == -1) {
963 fprintf(stderr, "\'%s", argv[0]); 968 fprintf(output, "\'%s", argv[0]);
964 for (i = 1; i < argc; i++) 969 for (i = 1; i < argc; i++)
965 fprintf(stderr, " %s", argv[i]); 970 fprintf(output, " %s", argv[i]);
966 } else if (target_pid != -1) 971 } else if (target_pid != -1)
967 fprintf(stderr, "process id \'%d", target_pid); 972 fprintf(output, "process id \'%d", target_pid);
968 else 973 else
969 fprintf(stderr, "thread id \'%d", target_tid); 974 fprintf(output, "thread id \'%d", target_tid);
970 975
971 fprintf(stderr, "\'"); 976 fprintf(output, "\'");
972 if (run_count > 1) 977 if (run_count > 1)
973 fprintf(stderr, " (%d runs)", run_count); 978 fprintf(output, " (%d runs)", run_count);
974 fprintf(stderr, ":\n\n"); 979 fprintf(output, ":\n\n");
975 } 980 }
976 981
977 if (no_aggr) { 982 if (no_aggr) {
@@ -984,15 +989,15 @@ static void print_stat(int argc, const char **argv)
984 989
985 if (!csv_output) { 990 if (!csv_output) {
986 if (!null_run) 991 if (!null_run)
987 fprintf(stderr, "\n"); 992 fprintf(output, "\n");
988 fprintf(stderr, " %17.9f seconds time elapsed", 993 fprintf(output, " %17.9f seconds time elapsed",
989 avg_stats(&walltime_nsecs_stats)/1e9); 994 avg_stats(&walltime_nsecs_stats)/1e9);
990 if (run_count > 1) { 995 if (run_count > 1) {
991 fprintf(stderr, " "); 996 fprintf(output, " ");
992 print_noise_pct(stddev_stats(&walltime_nsecs_stats), 997 print_noise_pct(stddev_stats(&walltime_nsecs_stats),
993 avg_stats(&walltime_nsecs_stats)); 998 avg_stats(&walltime_nsecs_stats));
994 } 999 }
995 fprintf(stderr, "\n\n"); 1000 fprintf(output, "\n\n");
996 } 1001 }
997} 1002}
998 1003
@@ -1030,6 +1035,8 @@ static int stat__set_big_num(const struct option *opt __used,
1030 return 0; 1035 return 0;
1031} 1036}
1032 1037
1038static bool append_file;
1039
1033static const struct option options[] = { 1040static const struct option options[] = {
1034 OPT_CALLBACK('e', "event", &evsel_list, "event", 1041 OPT_CALLBACK('e', "event", &evsel_list, "event",
1035 "event selector. use 'perf list' to list available events", 1042 "event selector. use 'perf list' to list available events",
@@ -1070,6 +1077,9 @@ static const struct option options[] = {
1070 OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1077 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1071 "monitor event in cgroup name only", 1078 "monitor event in cgroup name only",
1072 parse_cgroups), 1079 parse_cgroups),
1080 OPT_STRING('o', "output", &output_name, "file",
1081 "output file name"),
1082 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1073 OPT_END() 1083 OPT_END()
1074}; 1084};
1075 1085
@@ -1141,6 +1151,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1141{ 1151{
1142 struct perf_evsel *pos; 1152 struct perf_evsel *pos;
1143 int status = -ENOMEM; 1153 int status = -ENOMEM;
1154 const char *mode;
1144 1155
1145 setlocale(LC_ALL, ""); 1156 setlocale(LC_ALL, "");
1146 1157
@@ -1151,6 +1162,23 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1151 argc = parse_options(argc, argv, options, stat_usage, 1162 argc = parse_options(argc, argv, options, stat_usage,
1152 PARSE_OPT_STOP_AT_NON_OPTION); 1163 PARSE_OPT_STOP_AT_NON_OPTION);
1153 1164
1165 output = stderr;
1166 if (output_name && strcmp(output_name, "-"))
1167 output = NULL;
1168
1169 if (!output) {
1170 struct timespec tm;
1171 mode = append_file ? "a" : "w";
1172
1173 output = fopen(output_name, mode);
1174 if (!output) {
1175 perror("failed to create output file");
1176 exit(-1);
1177 }
1178 clock_gettime(CLOCK_REALTIME, &tm);
1179 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1180 }
1181
1154 if (csv_sep) 1182 if (csv_sep)
1155 csv_output = true; 1183 csv_output = true;
1156 else 1184 else
@@ -1226,7 +1254,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1226 status = 0; 1254 status = 0;
1227 for (run_idx = 0; run_idx < run_count; run_idx++) { 1255 for (run_idx = 0; run_idx < run_count; run_idx++) {
1228 if (run_count != 1 && verbose) 1256 if (run_count != 1 && verbose)
1229 fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); 1257 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1258 run_idx + 1);
1230 1259
1231 if (sync_run) 1260 if (sync_run)
1232 sync(); 1261 sync();
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index e01af2b1a469..01d36ba54053 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -324,9 +324,12 @@ fallback:
324 324
325 snprintf(command, sizeof(command), 325 snprintf(command, sizeof(command),
326 "objdump --start-address=0x%016" PRIx64 326 "objdump --start-address=0x%016" PRIx64
327 " --stop-address=0x%016" PRIx64 " -dS -C %s|grep -v %s|expand", 327 " --stop-address=0x%016" PRIx64
328 " -d %s %s -C %s|grep -v %s|expand",
328 map__rip_2objdump(map, sym->start), 329 map__rip_2objdump(map, sym->start),
329 map__rip_2objdump(map, sym->end), 330 map__rip_2objdump(map, sym->end),
331 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
332 symbol_conf.annotate_src ? "-S" : "",
330 symfs_filename, filename); 333 symfs_filename, filename);
331 334
332 pr_debug("Executing: %s\n", command); 335 pr_debug("Executing: %s\n", command);
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index e191eb9a667f..521c38a79190 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -200,7 +200,7 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
200 * Auto-detect: 200 * Auto-detect:
201 */ 201 */
202 if (perf_use_color_default < 0) { 202 if (perf_use_color_default < 0) {
203 if (isatty(1) || pager_in_use()) 203 if (isatty(fileno(fp)) || pager_in_use())
204 perf_use_color_default = 1; 204 perf_use_color_default = 1;
205 else 205 else
206 perf_use_color_default = 0; 206 perf_use_color_default = 0;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 469c0264ed29..245e60d6b4e7 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -46,6 +46,8 @@ struct symbol_conf symbol_conf = {
46 .exclude_other = true, 46 .exclude_other = true,
47 .use_modules = true, 47 .use_modules = true,
48 .try_vmlinux_path = true, 48 .try_vmlinux_path = true,
49 .annotate_asm_raw = true,
50 .annotate_src = true,
49 .symfs = "", 51 .symfs = "",
50}; 52};
51 53
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4f377d92e75a..7733f0b3cd41 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -76,7 +76,9 @@ struct symbol_conf {
76 exclude_other, 76 exclude_other,
77 show_cpu_utilization, 77 show_cpu_utilization,
78 initialized, 78 initialized,
79 kptr_restrict; 79 kptr_restrict,
80 annotate_asm_raw,
81 annotate_src;
80 const char *vmlinux_name, 82 const char *vmlinux_name,
81 *kallsyms_name, 83 *kallsyms_name,
82 *source_prefix, 84 *source_prefix,