aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-04 13:48:30 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-04 13:48:30 -0500
commit394efd19d5fcae936261bd48e5b33b21897aacf8 (patch)
treec48cf3ddbb07fd87309f1abdf31a27c71330e587 /tools/perf
parentf421436a591d34fa5279b54a96ac07d70250cc8d (diff)
parentbe408cd3e1fef73e9408b196a79b9934697fe3b1 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/emulex/benet/be.h drivers/net/netconsole.c net/bridge/br_private.h Three mostly trivial conflicts. The net/bridge/br_private.h conflict was a function signature (argument addition) change overlapping with the extern removals from Joe Perches. In drivers/net/netconsole.c we had one change adjusting a printk message whilst another changed "printk(KERN_INFO" into "pr_info(". Lastly, the emulex change was a new inline function addition overlapping with Joe Perches's extern removals. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-record.txt14
-rw-r--r--tools/perf/Documentation/perf-top.txt18
-rw-r--r--tools/perf/builtin-kvm.c7
-rw-r--r--tools/perf/builtin-record.c73
-rw-r--r--tools/perf/builtin-top.c33
-rw-r--r--tools/perf/builtin-trace.c8
-rw-r--r--tools/perf/tests/code-reading.c1
-rw-r--r--tools/perf/tests/keep-tracking.c1
-rw-r--r--tools/perf/tests/mmap-basic.c1
-rw-r--r--tools/perf/tests/open-syscall-tp-fields.c4
-rw-r--r--tools/perf/tests/perf-record.c2
-rw-r--r--tools/perf/tests/perf-time-to-tsc.c4
-rw-r--r--tools/perf/tests/sw-clock.c4
-rw-r--r--tools/perf/tests/task-exit.c6
-rw-r--r--tools/perf/ui/stdio/hist.c9
-rw-r--r--tools/perf/util/callchain.h3
-rw-r--r--tools/perf/util/event.c32
-rw-r--r--tools/perf/util/evlist.c13
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/hist.h13
-rw-r--r--tools/perf/util/probe-finder.c2
-rw-r--r--tools/perf/util/python.c2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c2
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c37
25 files changed, 191 insertions, 101 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index e297b74471b8..ca0d3d9f4bac 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -90,8 +90,20 @@ OPTIONS
90 Number of mmap data pages. Must be a power of two. 90 Number of mmap data pages. Must be a power of two.
91 91
92-g:: 92-g::
93 Enables call-graph (stack chain/backtrace) recording.
94
93--call-graph:: 95--call-graph::
94 Do call-graph (stack chain/backtrace) recording. 96 Setup and enable call-graph (stack chain/backtrace) recording,
97 implies -g.
98
99 Allows specifying "fp" (frame pointer) or "dwarf"
100 (DWARF's CFI - Call Frame Information) as the method to collect
101 the information used to show the call graphs.
102
103 In some systems, where binaries are build with gcc
104 --fomit-frame-pointer, using the "fp" method will produce bogus
105 call graphs, using "dwarf", if available (perf tools linked to
106 the libunwind library) should be used instead.
95 107
96-q:: 108-q::
97--quiet:: 109--quiet::
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 58d6598a9686..6a118e71d003 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -140,20 +140,12 @@ Default is to monitor all CPUS.
140--asm-raw:: 140--asm-raw::
141 Show raw instruction encoding of assembly instructions. 141 Show raw instruction encoding of assembly instructions.
142 142
143-G [type,min,order]:: 143-G::
144 Enables call-graph (stack chain/backtrace) recording.
145
144--call-graph:: 146--call-graph::
145 Display call chains using type, min percent threshold and order. 147 Setup and enable call-graph (stack chain/backtrace) recording,
146 type can be either: 148 implies -G.
147 - flat: single column, linear exposure of call chains.
148 - graph: use a graph tree, displaying absolute overhead rates.
149 - fractal: like graph, but displays relative rates. Each branch of
150 the tree is considered as a new profiled object.
151
152 order can be either:
153 - callee: callee based call graph.
154 - caller: inverted caller based call graph.
155
156 Default: fractal,0.5,callee.
157 149
158--ignore-callees=<regex>:: 150--ignore-callees=<regex>::
159 Ignore callees of the function(s) matching the given regex. 151 Ignore callees of the function(s) matching the given regex.
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 935d52216c89..fbc2888d6495 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -888,11 +888,18 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
888 while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) { 888 while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) {
889 err = perf_evlist__parse_sample(kvm->evlist, event, &sample); 889 err = perf_evlist__parse_sample(kvm->evlist, event, &sample);
890 if (err) { 890 if (err) {
891 perf_evlist__mmap_consume(kvm->evlist, idx);
891 pr_err("Failed to parse sample\n"); 892 pr_err("Failed to parse sample\n");
892 return -1; 893 return -1;
893 } 894 }
894 895
895 err = perf_session_queue_event(kvm->session, event, &sample, 0); 896 err = perf_session_queue_event(kvm->session, event, &sample, 0);
897 /*
898 * FIXME: Here we can't consume the event, as perf_session_queue_event will
899 * point to it, and it'll get possibly overwritten by the kernel.
900 */
901 perf_evlist__mmap_consume(kvm->evlist, idx);
902
896 if (err) { 903 if (err) {
897 pr_err("Failed to enqueue sample: %d\n", err); 904 pr_err("Failed to enqueue sample: %d\n", err);
898 return -1; 905 return -1;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a41ac41546c9..d04651484640 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -712,21 +712,12 @@ static int get_stack_size(char *str, unsigned long *_size)
712} 712}
713#endif /* LIBUNWIND_SUPPORT */ 713#endif /* LIBUNWIND_SUPPORT */
714 714
715int record_parse_callchain_opt(const struct option *opt, 715int record_parse_callchain(const char *arg, struct perf_record_opts *opts)
716 const char *arg, int unset)
717{ 716{
718 struct perf_record_opts *opts = opt->value;
719 char *tok, *name, *saveptr = NULL; 717 char *tok, *name, *saveptr = NULL;
720 char *buf; 718 char *buf;
721 int ret = -1; 719 int ret = -1;
722 720
723 /* --no-call-graph */
724 if (unset)
725 return 0;
726
727 /* We specified default option if none is provided. */
728 BUG_ON(!arg);
729
730 /* We need buffer that we know we can write to. */ 721 /* We need buffer that we know we can write to. */
731 buf = malloc(strlen(arg) + 1); 722 buf = malloc(strlen(arg) + 1);
732 if (!buf) 723 if (!buf)
@@ -764,13 +755,9 @@ int record_parse_callchain_opt(const struct option *opt,
764 ret = get_stack_size(tok, &size); 755 ret = get_stack_size(tok, &size);
765 opts->stack_dump_size = size; 756 opts->stack_dump_size = size;
766 } 757 }
767
768 if (!ret)
769 pr_debug("callchain: stack dump size %d\n",
770 opts->stack_dump_size);
771#endif /* LIBUNWIND_SUPPORT */ 758#endif /* LIBUNWIND_SUPPORT */
772 } else { 759 } else {
773 pr_err("callchain: Unknown -g option " 760 pr_err("callchain: Unknown --call-graph option "
774 "value: %s\n", arg); 761 "value: %s\n", arg);
775 break; 762 break;
776 } 763 }
@@ -778,13 +765,52 @@ int record_parse_callchain_opt(const struct option *opt,
778 } while (0); 765 } while (0);
779 766
780 free(buf); 767 free(buf);
768 return ret;
769}
770
771static void callchain_debug(struct perf_record_opts *opts)
772{
773 pr_debug("callchain: type %d\n", opts->call_graph);
781 774
775 if (opts->call_graph == CALLCHAIN_DWARF)
776 pr_debug("callchain: stack dump size %d\n",
777 opts->stack_dump_size);
778}
779
780int record_parse_callchain_opt(const struct option *opt,
781 const char *arg,
782 int unset)
783{
784 struct perf_record_opts *opts = opt->value;
785 int ret;
786
787 /* --no-call-graph */
788 if (unset) {
789 opts->call_graph = CALLCHAIN_NONE;
790 pr_debug("callchain: disabled\n");
791 return 0;
792 }
793
794 ret = record_parse_callchain(arg, opts);
782 if (!ret) 795 if (!ret)
783 pr_debug("callchain: type %d\n", opts->call_graph); 796 callchain_debug(opts);
784 797
785 return ret; 798 return ret;
786} 799}
787 800
801int record_callchain_opt(const struct option *opt,
802 const char *arg __maybe_unused,
803 int unset __maybe_unused)
804{
805 struct perf_record_opts *opts = opt->value;
806
807 if (opts->call_graph == CALLCHAIN_NONE)
808 opts->call_graph = CALLCHAIN_FP;
809
810 callchain_debug(opts);
811 return 0;
812}
813
788static const char * const record_usage[] = { 814static const char * const record_usage[] = {
789 "perf record [<options>] [<command>]", 815 "perf record [<options>] [<command>]",
790 "perf record [<options>] -- <command> [<options>]", 816 "perf record [<options>] -- <command> [<options>]",
@@ -813,12 +839,12 @@ static struct perf_record record = {
813 }, 839 },
814}; 840};
815 841
816#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: " 842#define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: "
817 843
818#ifdef LIBUNWIND_SUPPORT 844#ifdef LIBUNWIND_SUPPORT
819const char record_callchain_help[] = CALLCHAIN_HELP "[fp] dwarf"; 845const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf";
820#else 846#else
821const char record_callchain_help[] = CALLCHAIN_HELP "[fp]"; 847const char record_callchain_help[] = CALLCHAIN_HELP "fp";
822#endif 848#endif
823 849
824/* 850/*
@@ -858,9 +884,12 @@ const struct option record_options[] = {
858 "number of mmap data pages"), 884 "number of mmap data pages"),
859 OPT_BOOLEAN(0, "group", &record.opts.group, 885 OPT_BOOLEAN(0, "group", &record.opts.group,
860 "put the counters into a counter group"), 886 "put the counters into a counter group"),
861 OPT_CALLBACK_DEFAULT('g', "call-graph", &record.opts, 887 OPT_CALLBACK_NOOPT('g', NULL, &record.opts,
862 "mode[,dump_size]", record_callchain_help, 888 NULL, "enables call-graph recording" ,
863 &record_parse_callchain_opt, "fp"), 889 &record_callchain_opt),
890 OPT_CALLBACK(0, "call-graph", &record.opts,
891 "mode[,dump_size]", record_callchain_help,
892 &record_parse_callchain_opt),
864 OPT_INCR('v', "verbose", &verbose, 893 OPT_INCR('v', "verbose", &verbose,
865 "be more verbose (show counter open errors, etc)"), 894 "be more verbose (show counter open errors, etc)"),
866 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 895 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 212214162bb2..5a11f13e56f9 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -810,7 +810,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
810 ret = perf_evlist__parse_sample(top->evlist, event, &sample); 810 ret = perf_evlist__parse_sample(top->evlist, event, &sample);
811 if (ret) { 811 if (ret) {
812 pr_err("Can't parse sample, err = %d\n", ret); 812 pr_err("Can't parse sample, err = %d\n", ret);
813 continue; 813 goto next_event;
814 } 814 }
815 815
816 evsel = perf_evlist__id2evsel(session->evlist, sample.id); 816 evsel = perf_evlist__id2evsel(session->evlist, sample.id);
@@ -825,13 +825,13 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
825 case PERF_RECORD_MISC_USER: 825 case PERF_RECORD_MISC_USER:
826 ++top->us_samples; 826 ++top->us_samples;
827 if (top->hide_user_symbols) 827 if (top->hide_user_symbols)
828 continue; 828 goto next_event;
829 machine = &session->machines.host; 829 machine = &session->machines.host;
830 break; 830 break;
831 case PERF_RECORD_MISC_KERNEL: 831 case PERF_RECORD_MISC_KERNEL:
832 ++top->kernel_samples; 832 ++top->kernel_samples;
833 if (top->hide_kernel_symbols) 833 if (top->hide_kernel_symbols)
834 continue; 834 goto next_event;
835 machine = &session->machines.host; 835 machine = &session->machines.host;
836 break; 836 break;
837 case PERF_RECORD_MISC_GUEST_KERNEL: 837 case PERF_RECORD_MISC_GUEST_KERNEL:
@@ -847,7 +847,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
847 */ 847 */
848 /* Fall thru */ 848 /* Fall thru */
849 default: 849 default:
850 continue; 850 goto next_event;
851 } 851 }
852 852
853 853
@@ -859,6 +859,8 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
859 machine__process_event(machine, event); 859 machine__process_event(machine, event);
860 } else 860 } else
861 ++session->stats.nr_unknown_events; 861 ++session->stats.nr_unknown_events;
862next_event:
863 perf_evlist__mmap_consume(top->evlist, idx);
862 } 864 }
863} 865}
864 866
@@ -1016,16 +1018,16 @@ out_delete:
1016} 1018}
1017 1019
1018static int 1020static int
1019parse_callchain_opt(const struct option *opt, const char *arg, int unset) 1021callchain_opt(const struct option *opt, const char *arg, int unset)
1020{ 1022{
1021 /*
1022 * --no-call-graph
1023 */
1024 if (unset)
1025 return 0;
1026
1027 symbol_conf.use_callchain = true; 1023 symbol_conf.use_callchain = true;
1024 return record_callchain_opt(opt, arg, unset);
1025}
1028 1026
1027static int
1028parse_callchain_opt(const struct option *opt, const char *arg, int unset)
1029{
1030 symbol_conf.use_callchain = true;
1029 return record_parse_callchain_opt(opt, arg, unset); 1031 return record_parse_callchain_opt(opt, arg, unset);
1030} 1032}
1031 1033
@@ -1106,9 +1108,12 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1106 "sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight"), 1108 "sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight"),
1107 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, 1109 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1108 "Show a column with the number of samples"), 1110 "Show a column with the number of samples"),
1109 OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts, 1111 OPT_CALLBACK_NOOPT('G', NULL, &top.record_opts,
1110 "mode[,dump_size]", record_callchain_help, 1112 NULL, "enables call-graph recording",
1111 &parse_callchain_opt, "fp"), 1113 &callchain_opt),
1114 OPT_CALLBACK(0, "call-graph", &top.record_opts,
1115 "mode[,dump_size]", record_callchain_help,
1116 &parse_callchain_opt),
1112 OPT_CALLBACK(0, "ignore-callees", NULL, "regex", 1117 OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
1113 "ignore callees of these functions in call graphs", 1118 "ignore callees of these functions in call graphs",
1114 report_parse_ignore_callees_opt), 1119 report_parse_ignore_callees_opt),
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 71aa3e35406b..99c8d9ad6729 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -987,7 +987,7 @@ again:
987 err = perf_evlist__parse_sample(evlist, event, &sample); 987 err = perf_evlist__parse_sample(evlist, event, &sample);
988 if (err) { 988 if (err) {
989 fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err); 989 fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err);
990 continue; 990 goto next_event;
991 } 991 }
992 992
993 if (trace->base_time == 0) 993 if (trace->base_time == 0)
@@ -1001,18 +1001,20 @@ again:
1001 evsel = perf_evlist__id2evsel(evlist, sample.id); 1001 evsel = perf_evlist__id2evsel(evlist, sample.id);
1002 if (evsel == NULL) { 1002 if (evsel == NULL) {
1003 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); 1003 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id);
1004 continue; 1004 goto next_event;
1005 } 1005 }
1006 1006
1007 if (sample.raw_data == NULL) { 1007 if (sample.raw_data == NULL) {
1008 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", 1008 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
1009 perf_evsel__name(evsel), sample.tid, 1009 perf_evsel__name(evsel), sample.tid,
1010 sample.cpu, sample.raw_size); 1010 sample.cpu, sample.raw_size);
1011 continue; 1011 goto next_event;
1012 } 1012 }
1013 1013
1014 handler = evsel->handler.func; 1014 handler = evsel->handler.func;
1015 handler(trace, evsel, &sample); 1015 handler(trace, evsel, &sample);
1016next_event:
1017 perf_evlist__mmap_consume(evlist, i);
1016 1018
1017 if (done) 1019 if (done)
1018 goto out_unmap_evlist; 1020 goto out_unmap_evlist;
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 6fb781d5586c..e3fedfa2906e 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -290,6 +290,7 @@ static int process_events(struct machine *machine, struct perf_evlist *evlist,
290 for (i = 0; i < evlist->nr_mmaps; i++) { 290 for (i = 0; i < evlist->nr_mmaps; i++) {
291 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { 291 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
292 ret = process_event(machine, evlist, event, state); 292 ret = process_event(machine, evlist, event, state);
293 perf_evlist__mmap_consume(evlist, i);
293 if (ret < 0) 294 if (ret < 0)
294 return ret; 295 return ret;
295 } 296 }
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index d444ea2c47d9..376c35608534 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -36,6 +36,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm)
36 (pid_t)event->comm.tid == getpid() && 36 (pid_t)event->comm.tid == getpid() &&
37 strcmp(event->comm.comm, comm) == 0) 37 strcmp(event->comm.comm, comm) == 0)
38 found += 1; 38 found += 1;
39 perf_evlist__mmap_consume(evlist, i);
39 } 40 }
40 } 41 }
41 return found; 42 return found;
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index c4185b9aeb80..a7232c204eb9 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -122,6 +122,7 @@ int test__basic_mmap(void)
122 goto out_munmap; 122 goto out_munmap;
123 } 123 }
124 nr_events[evsel->idx]++; 124 nr_events[evsel->idx]++;
125 perf_evlist__mmap_consume(evlist, 0);
125 } 126 }
126 127
127 err = 0; 128 err = 0;
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index fc5b9fca8b47..524b221b829b 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -77,8 +77,10 @@ int test__syscall_open_tp_fields(void)
77 77
78 ++nr_events; 78 ++nr_events;
79 79
80 if (type != PERF_RECORD_SAMPLE) 80 if (type != PERF_RECORD_SAMPLE) {
81 perf_evlist__mmap_consume(evlist, i);
81 continue; 82 continue;
83 }
82 84
83 err = perf_evsel__parse_sample(evsel, event, &sample); 85 err = perf_evsel__parse_sample(evsel, event, &sample);
84 if (err) { 86 if (err) {
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index b8a7056519ac..7923b06ffc91 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -263,6 +263,8 @@ int test__PERF_RECORD(void)
263 type); 263 type);
264 ++errs; 264 ++errs;
265 } 265 }
266
267 perf_evlist__mmap_consume(evlist, i);
266 } 268 }
267 } 269 }
268 270
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 0ab61b1f408e..4ca1b938f6a6 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -122,7 +122,7 @@ int test__perf_time_to_tsc(void)
122 if (event->header.type != PERF_RECORD_COMM || 122 if (event->header.type != PERF_RECORD_COMM ||
123 (pid_t)event->comm.pid != getpid() || 123 (pid_t)event->comm.pid != getpid() ||
124 (pid_t)event->comm.tid != getpid()) 124 (pid_t)event->comm.tid != getpid())
125 continue; 125 goto next_event;
126 126
127 if (strcmp(event->comm.comm, comm1) == 0) { 127 if (strcmp(event->comm.comm, comm1) == 0) {
128 CHECK__(perf_evsel__parse_sample(evsel, event, 128 CHECK__(perf_evsel__parse_sample(evsel, event,
@@ -134,6 +134,8 @@ int test__perf_time_to_tsc(void)
134 &sample)); 134 &sample));
135 comm2_time = sample.time; 135 comm2_time = sample.time;
136 } 136 }
137next_event:
138 perf_evlist__mmap_consume(evlist, i);
137 } 139 }
138 } 140 }
139 141
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 2e41e2d32ccc..6e2b44ec0749 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -78,7 +78,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
78 struct perf_sample sample; 78 struct perf_sample sample;
79 79
80 if (event->header.type != PERF_RECORD_SAMPLE) 80 if (event->header.type != PERF_RECORD_SAMPLE)
81 continue; 81 goto next_event;
82 82
83 err = perf_evlist__parse_sample(evlist, event, &sample); 83 err = perf_evlist__parse_sample(evlist, event, &sample);
84 if (err < 0) { 84 if (err < 0) {
@@ -88,6 +88,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
88 88
89 total_periods += sample.period; 89 total_periods += sample.period;
90 nr_samples++; 90 nr_samples++;
91next_event:
92 perf_evlist__mmap_consume(evlist, 0);
91 } 93 }
92 94
93 if ((u64) nr_samples == total_periods) { 95 if ((u64) nr_samples == total_periods) {
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 28fe5894b061..a3e64876e940 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -96,10 +96,10 @@ int test__task_exit(void)
96 96
97retry: 97retry:
98 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { 98 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
99 if (event->header.type != PERF_RECORD_EXIT) 99 if (event->header.type == PERF_RECORD_EXIT)
100 continue; 100 nr_exit++;
101 101
102 nr_exit++; 102 perf_evlist__mmap_consume(evlist, 0);
103 } 103 }
104 104
105 if (!exited || !nr_exit) { 105 if (!exited || !nr_exit) {
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 194e2f42ff5d..6c152686e837 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -315,8 +315,7 @@ static inline void advance_hpp(struct perf_hpp *hpp, int inc)
315} 315}
316 316
317static int hist_entry__period_snprintf(struct perf_hpp *hpp, 317static int hist_entry__period_snprintf(struct perf_hpp *hpp,
318 struct hist_entry *he, 318 struct hist_entry *he)
319 bool color)
320{ 319{
321 const char *sep = symbol_conf.field_sep; 320 const char *sep = symbol_conf.field_sep;
322 struct perf_hpp_fmt *fmt; 321 struct perf_hpp_fmt *fmt;
@@ -338,7 +337,7 @@ static int hist_entry__period_snprintf(struct perf_hpp *hpp,
338 } else 337 } else
339 first = false; 338 first = false;
340 339
341 if (color && fmt->color) 340 if (perf_hpp__use_color() && fmt->color)
342 ret = fmt->color(fmt, hpp, he); 341 ret = fmt->color(fmt, hpp, he);
343 else 342 else
344 ret = fmt->entry(fmt, hpp, he); 343 ret = fmt->entry(fmt, hpp, he);
@@ -358,12 +357,11 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
358 .buf = bf, 357 .buf = bf,
359 .size = size, 358 .size = size,
360 }; 359 };
361 bool color = !symbol_conf.field_sep;
362 360
363 if (size == 0 || size > bfsz) 361 if (size == 0 || size > bfsz)
364 size = hpp.size = bfsz; 362 size = hpp.size = bfsz;
365 363
366 ret = hist_entry__period_snprintf(&hpp, he, color); 364 ret = hist_entry__period_snprintf(&hpp, he);
367 hist_entry__sort_snprintf(he, bf + ret, size - ret, hists); 365 hist_entry__sort_snprintf(he, bf + ret, size - ret, hists);
368 366
369 ret = fprintf(fp, "%s\n", bf); 367 ret = fprintf(fp, "%s\n", bf);
@@ -482,6 +480,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
482 480
483print_entries: 481print_entries:
484 linesz = hists__sort_list_width(hists) + 3 + 1; 482 linesz = hists__sort_list_width(hists) + 3 + 1;
483 linesz += perf_hpp__color_overhead();
485 line = malloc(linesz); 484 line = malloc(linesz);
486 if (line == NULL) { 485 if (line == NULL) {
487 ret = -1; 486 ret = -1;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 2b585bc308cf..9e99060408ae 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -147,6 +147,9 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
147 147
148struct option; 148struct option;
149 149
150int record_parse_callchain(const char *arg, struct perf_record_opts *opts);
150int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset); 151int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
152int record_callchain_opt(const struct option *opt, const char *arg, int unset);
153
151extern const char record_callchain_help[]; 154extern const char record_callchain_help[];
152#endif /* __PERF_CALLCHAIN_H */ 155#endif /* __PERF_CALLCHAIN_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 9b393e7dca6f..49096ea58a15 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -187,7 +187,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
187 return -1; 187 return -1;
188 } 188 }
189 189
190 event->header.type = PERF_RECORD_MMAP2; 190 event->header.type = PERF_RECORD_MMAP;
191 /* 191 /*
192 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c 192 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
193 */ 193 */
@@ -198,7 +198,6 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
198 char prot[5]; 198 char prot[5];
199 char execname[PATH_MAX]; 199 char execname[PATH_MAX];
200 char anonstr[] = "//anon"; 200 char anonstr[] = "//anon";
201 unsigned int ino;
202 size_t size; 201 size_t size;
203 ssize_t n; 202 ssize_t n;
204 203
@@ -209,15 +208,12 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
209 strcpy(execname, ""); 208 strcpy(execname, "");
210 209
211 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ 210 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
212 n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n", 211 n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n",
213 &event->mmap2.start, &event->mmap2.len, prot, 212 &event->mmap.start, &event->mmap.len, prot,
214 &event->mmap2.pgoff, &event->mmap2.maj, 213 &event->mmap.pgoff,
215 &event->mmap2.min, 214 execname);
216 &ino, execname);
217
218 event->mmap2.ino = (u64)ino;
219 215
220 if (n != 8) 216 if (n != 5)
221 continue; 217 continue;
222 218
223 if (prot[2] != 'x') 219 if (prot[2] != 'x')
@@ -227,15 +223,15 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool,
227 strcpy(execname, anonstr); 223 strcpy(execname, anonstr);
228 224
229 size = strlen(execname) + 1; 225 size = strlen(execname) + 1;
230 memcpy(event->mmap2.filename, execname, size); 226 memcpy(event->mmap.filename, execname, size);
231 size = PERF_ALIGN(size, sizeof(u64)); 227 size = PERF_ALIGN(size, sizeof(u64));
232 event->mmap2.len -= event->mmap.start; 228 event->mmap.len -= event->mmap.start;
233 event->mmap2.header.size = (sizeof(event->mmap2) - 229 event->mmap.header.size = (sizeof(event->mmap) -
234 (sizeof(event->mmap2.filename) - size)); 230 (sizeof(event->mmap.filename) - size));
235 memset(event->mmap2.filename + size, 0, machine->id_hdr_size); 231 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
236 event->mmap2.header.size += machine->id_hdr_size; 232 event->mmap.header.size += machine->id_hdr_size;
237 event->mmap2.pid = tgid; 233 event->mmap.pid = tgid;
238 event->mmap2.tid = pid; 234 event->mmap.tid = pid;
239 235
240 if (process(tool, event, &synth_sample, machine) != 0) { 236 if (process(tool, event, &synth_sample, machine) != 0) {
241 rc = -1; 237 rc = -1;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index f9f77bee0b1b..e584cd30b0f2 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -545,12 +545,19 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
545 545
546 md->prev = old; 546 md->prev = old;
547 547
548 if (!evlist->overwrite)
549 perf_mmap__write_tail(md, old);
550
551 return event; 548 return event;
552} 549}
553 550
551void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
552{
553 if (!evlist->overwrite) {
554 struct perf_mmap *md = &evlist->mmap[idx];
555 unsigned int old = md->prev;
556
557 perf_mmap__write_tail(md, old);
558 }
559}
560
554static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx) 561static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
555{ 562{
556 if (evlist->mmap[idx].base != NULL) { 563 if (evlist->mmap[idx].base != NULL) {
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 880d7139d2fb..206d09339306 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -89,6 +89,8 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
89 89
90union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); 90union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
91 91
92void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
93
92int perf_evlist__open(struct perf_evlist *evlist); 94int perf_evlist__open(struct perf_evlist *evlist);
93void perf_evlist__close(struct perf_evlist *evlist); 95void perf_evlist__close(struct perf_evlist *evlist);
94 96
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0ce9febf1ba0..9f1ef9bee2d0 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -678,7 +678,6 @@ void perf_evsel__config(struct perf_evsel *evsel,
678 attr->sample_type |= PERF_SAMPLE_WEIGHT; 678 attr->sample_type |= PERF_SAMPLE_WEIGHT;
679 679
680 attr->mmap = track; 680 attr->mmap = track;
681 attr->mmap2 = track && !perf_missing_features.mmap2;
682 attr->comm = track; 681 attr->comm = track;
683 682
684 /* 683 /*
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 1329b6b6ffe6..ce8dc61ce2c3 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -5,6 +5,7 @@
5#include <pthread.h> 5#include <pthread.h>
6#include "callchain.h" 6#include "callchain.h"
7#include "header.h" 7#include "header.h"
8#include "color.h"
8 9
9extern struct callchain_param callchain_param; 10extern struct callchain_param callchain_param;
10 11
@@ -175,6 +176,18 @@ void perf_hpp__init(void);
175void perf_hpp__column_register(struct perf_hpp_fmt *format); 176void perf_hpp__column_register(struct perf_hpp_fmt *format);
176void perf_hpp__column_enable(unsigned col); 177void perf_hpp__column_enable(unsigned col);
177 178
179static inline size_t perf_hpp__use_color(void)
180{
181 return !symbol_conf.field_sep;
182}
183
184static inline size_t perf_hpp__color_overhead(void)
185{
186 return perf_hpp__use_color() ?
187 (COLOR_MAXLEN + sizeof(PERF_COLOR_RESET)) * PERF_HPP__MAX_INDEX
188 : 0;
189}
190
178struct perf_evlist; 191struct perf_evlist;
179 192
180struct hist_browser_timer { 193struct hist_browser_timer {
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index c09e0a9fdf4c..f0692737ebf1 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1357,10 +1357,10 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
1357 goto post; 1357 goto post;
1358 } 1358 }
1359 1359
1360 fname = dwarf_decl_file(&spdie);
1360 if (addr == (unsigned long)baseaddr) { 1361 if (addr == (unsigned long)baseaddr) {
1361 /* Function entry - Relative line number is 0 */ 1362 /* Function entry - Relative line number is 0 */
1362 lineno = baseline; 1363 lineno = baseline;
1363 fname = dwarf_decl_file(&spdie);
1364 goto post; 1364 goto post;
1365 } 1365 }
1366 1366
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 71b5412bbbb9..2ac4bc92bb1f 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -822,6 +822,8 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
822 PyObject *pyevent = pyrf_event__new(event); 822 PyObject *pyevent = pyrf_event__new(event);
823 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 823 struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
824 824
825 perf_evlist__mmap_consume(evlist, cpu);
826
825 if (pyevent == NULL) 827 if (pyevent == NULL)
826 return PyErr_NoMemory(); 828 return PyErr_NoMemory();
827 829
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index a85e4ae5f3ac..c0c9795c4f02 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -282,7 +282,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
282 282
283 event = find_cache_event(evsel); 283 event = find_cache_event(evsel);
284 if (!event) 284 if (!event)
285 die("ug! no event found for type %" PRIu64, evsel->attr.config); 285 die("ug! no event found for type %" PRIu64, (u64)evsel->attr.config);
286 286
287 pid = raw_field_value(event, "common_pid", data); 287 pid = raw_field_value(event, "common_pid", data);
288 288
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index cc75a3cef388..95d91a0b23af 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -56,6 +56,17 @@ static void handler_call_die(const char *handler_name)
56 Py_FatalError("problem in Python trace event handler"); 56 Py_FatalError("problem in Python trace event handler");
57} 57}
58 58
59/*
60 * Insert val into into the dictionary and decrement the reference counter.
61 * This is necessary for dictionaries since PyDict_SetItemString() does not
62 * steal a reference, as opposed to PyTuple_SetItem().
63 */
64static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObject *val)
65{
66 PyDict_SetItemString(dict, key, val);
67 Py_DECREF(val);
68}
69
59static void define_value(enum print_arg_type field_type, 70static void define_value(enum print_arg_type field_type,
60 const char *ev_name, 71 const char *ev_name,
61 const char *field_name, 72 const char *field_name,
@@ -279,11 +290,11 @@ static void python_process_tracepoint(union perf_event *perf_event
279 PyTuple_SetItem(t, n++, PyInt_FromLong(pid)); 290 PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
280 PyTuple_SetItem(t, n++, PyString_FromString(comm)); 291 PyTuple_SetItem(t, n++, PyString_FromString(comm));
281 } else { 292 } else {
282 PyDict_SetItemString(dict, "common_cpu", PyInt_FromLong(cpu)); 293 pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
283 PyDict_SetItemString(dict, "common_s", PyInt_FromLong(s)); 294 pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
284 PyDict_SetItemString(dict, "common_ns", PyInt_FromLong(ns)); 295 pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
285 PyDict_SetItemString(dict, "common_pid", PyInt_FromLong(pid)); 296 pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
286 PyDict_SetItemString(dict, "common_comm", PyString_FromString(comm)); 297 pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
287 } 298 }
288 for (field = event->format.fields; field; field = field->next) { 299 for (field = event->format.fields; field; field = field->next) {
289 if (field->flags & FIELD_IS_STRING) { 300 if (field->flags & FIELD_IS_STRING) {
@@ -313,7 +324,7 @@ static void python_process_tracepoint(union perf_event *perf_event
313 if (handler) 324 if (handler)
314 PyTuple_SetItem(t, n++, obj); 325 PyTuple_SetItem(t, n++, obj);
315 else 326 else
316 PyDict_SetItemString(dict, field->name, obj); 327 pydict_set_item_string_decref(dict, field->name, obj);
317 328
318 } 329 }
319 if (!handler) 330 if (!handler)
@@ -370,21 +381,21 @@ static void python_process_general_event(union perf_event *perf_event
370 if (!handler || !PyCallable_Check(handler)) 381 if (!handler || !PyCallable_Check(handler))
371 goto exit; 382 goto exit;
372 383
373 PyDict_SetItemString(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); 384 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
374 PyDict_SetItemString(dict, "attr", PyString_FromStringAndSize( 385 pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
375 (const char *)&evsel->attr, sizeof(evsel->attr))); 386 (const char *)&evsel->attr, sizeof(evsel->attr)));
376 PyDict_SetItemString(dict, "sample", PyString_FromStringAndSize( 387 pydict_set_item_string_decref(dict, "sample", PyString_FromStringAndSize(
377 (const char *)sample, sizeof(*sample))); 388 (const char *)sample, sizeof(*sample)));
378 PyDict_SetItemString(dict, "raw_buf", PyString_FromStringAndSize( 389 pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
379 (const char *)sample->raw_data, sample->raw_size)); 390 (const char *)sample->raw_data, sample->raw_size));
380 PyDict_SetItemString(dict, "comm", 391 pydict_set_item_string_decref(dict, "comm",
381 PyString_FromString(thread->comm)); 392 PyString_FromString(thread->comm));
382 if (al->map) { 393 if (al->map) {
383 PyDict_SetItemString(dict, "dso", 394 pydict_set_item_string_decref(dict, "dso",
384 PyString_FromString(al->map->dso->name)); 395 PyString_FromString(al->map->dso->name));
385 } 396 }
386 if (al->sym) { 397 if (al->sym) {
387 PyDict_SetItemString(dict, "symbol", 398 pydict_set_item_string_decref(dict, "symbol",
388 PyString_FromString(al->sym->name)); 399 PyString_FromString(al->sym->name));
389 } 400 }
390 401