aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-09-19 01:13:36 -0400
committerIngo Molnar <mingo@kernel.org>2014-09-19 01:13:36 -0400
commit4f7cf3a992cc0c15c97d2e34ea08a1cb7faace39 (patch)
treef65a2e146bbb838b882128e17d06a1b34e8fe63c
parentc88f2096136416b261bd3647cc260935f6e95805 (diff)
parente5685730e2c620f97bc12380e9370e857e5bd7a7 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: o Add +field argument support for --sort option (Jiri Olsa) o Do not access kallsyms when analyzing user binaries with 'probe' (Masami Hiramatsu) o Ignore stripped vmlinux and fallback to kallsyms (Anton Blanchard) o Add path to Ubuntu kernel debuginfo file (Anton Blanchard) o Disable kernel symbol demangling by default (Avi Kivity) Infrastructure changes: o More intel PT prep work, from Adrian Hunter, including: - Let a user specify a PMU event without any config terms - Add perf-with-kcore script - Let default config be defined for a PMU - Add perf_pmu__scan_file() o "perf kvm stat report" improvements by Alexander Yarygin: o Save pid string in opts.target.pid o Enable the target.system_wide flag o Unify the title bar output o Fix build issue on powerpc when DWARF support is disabled (Anton Blanchard) o Allow to specify lib compile variable for spec usage (Jiri Olsa) o Fix build on ARM (Stephane Eranian) o Fix build on powerpc when DWARF support is disabled (Anton Blanchard) o Don't include sys/poll.h directly (Arnaldo Carvalho de Melo) o Use ring buffer consume method to look like other tools (Arnaldo Carvalho de Melo) o Allow to specify lib compile variable for spec usage (Jiri Olsa) o Fix GNU-only grep usage in Makefile (John Spencer) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/perf/.gitignore1
-rw-r--r--tools/perf/Documentation/perf-probe.txt3
-rw-r--r--tools/perf/Documentation/perf-report.txt3
-rw-r--r--tools/perf/Documentation/perf-top.txt3
-rw-r--r--tools/perf/Makefile.perf5
-rw-r--r--tools/perf/arch/arm/tests/dwarf-unwind.c1
-rw-r--r--tools/perf/arch/arm/util/unwind-libunwind.c1
-rw-r--r--tools/perf/arch/powerpc/Makefile2
-rw-r--r--tools/perf/bench/sched-messaging.c2
-rw-r--r--tools/perf/builtin-kvm.c23
-rw-r--r--tools/perf/builtin-probe.c5
-rw-r--r--tools/perf/builtin-record.c8
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-top.c4
-rw-r--r--tools/perf/config/Makefile12
-rw-r--r--tools/perf/config/utilities.mak2
-rw-r--r--tools/perf/perf-with-kcore.sh259
-rw-r--r--tools/perf/tests/pmu.c2
-rw-r--r--tools/perf/util/kvm-stat.h1
-rw-r--r--tools/perf/util/parse-events.c13
-rw-r--r--tools/perf/util/parse-events.y10
-rw-r--r--tools/perf/util/pmu.c79
-rw-r--r--tools/perf/util/pmu.h12
-rw-r--r--tools/perf/util/probe-event.c9
-rw-r--r--tools/perf/util/probe-event.h3
-rw-r--r--tools/perf/util/probe-finder.c16
-rw-r--r--tools/perf/util/sort.c37
-rw-r--r--tools/perf/util/symbol-elf.c15
-rw-r--r--tools/perf/util/symbol.c9
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/util.h4
31 files changed, 487 insertions, 60 deletions
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 782d86e961b9..717221e98450 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -15,6 +15,7 @@ perf.data
15perf.data.old 15perf.data.old
16output.svg 16output.svg
17perf-archive 17perf-archive
18perf-with-kcore
18tags 19tags
19TAGS 20TAGS
20cscope* 21cscope*
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 1513935c399b..aaa869be3dc1 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -104,6 +104,9 @@ OPTIONS
104 Specify path to the executable or shared library file for user 104 Specify path to the executable or shared library file for user
105 space tracing. Can also be used with --funcs option. 105 space tracing. Can also be used with --funcs option.
106 106
107--demangle-kernel::
108 Demangle kernel symbols.
109
107In absence of -m/-x options, perf probe checks if the first argument after 110In absence of -m/-x options, perf probe checks if the first argument after
108the options is an absolute path name. If its an absolute path, perf probe 111the options is an absolute path name. If its an absolute path, perf probe
109uses it as a target module/target user space binary to probe. 112uses it as a target module/target user space binary to probe.
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index d561e0214f52..0927bf4e6c2a 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -276,6 +276,9 @@ OPTIONS
276 Demangle symbol names to human readable form. It's enabled by default, 276 Demangle symbol names to human readable form. It's enabled by default,
277 disable with --no-demangle. 277 disable with --no-demangle.
278 278
279--demangle-kernel::
280 Demangle kernel symbol names to human readable form (for C++ kernels).
281
279--mem-mode:: 282--mem-mode::
280 Use the data addresses of samples in addition to instruction addresses 283 Use the data addresses of samples in addition to instruction addresses
281 to build the histograms. To generate meaningful output, the perf.data 284 to build the histograms. To generate meaningful output, the perf.data
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 28fdee394880..3265b1070518 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -98,6 +98,9 @@ Default is to monitor all CPUS.
98--hide_user_symbols:: 98--hide_user_symbols::
99 Hide user symbols. 99 Hide user symbols.
100 100
101--demangle-kernel::
102 Demangle kernel symbols.
103
101-D:: 104-D::
102--dump-symtab:: 105--dump-symtab::
103 Dump the symbol table used for profiling. 106 Dump the symbol table used for profiling.
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 95e832b1bc3c..171f4e65601b 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -126,6 +126,7 @@ PYRF_OBJS =
126SCRIPT_SH = 126SCRIPT_SH =
127 127
128SCRIPT_SH += perf-archive.sh 128SCRIPT_SH += perf-archive.sh
129SCRIPT_SH += perf-with-kcore.sh
129 130
130grep-libs = $(filter -l%,$(1)) 131grep-libs = $(filter -l%,$(1))
131strip-libs = $(filter-out -l%,$(1)) 132strip-libs = $(filter-out -l%,$(1))
@@ -878,6 +879,8 @@ install-bin: all install-gtk
878 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 879 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
879 $(call QUIET_INSTALL, perf-archive) \ 880 $(call QUIET_INSTALL, perf-archive) \
880 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 881 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
882 $(call QUIET_INSTALL, perf-with-kcore) \
883 $(INSTALL) $(OUTPUT)perf-with-kcore -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
881ifndef NO_LIBPERL 884ifndef NO_LIBPERL
882 $(call QUIET_INSTALL, perl-scripts) \ 885 $(call QUIET_INSTALL, perl-scripts) \
883 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ 886 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
@@ -923,7 +926,7 @@ config-clean:
923 @$(MAKE) -C config/feature-checks clean >/dev/null 926 @$(MAKE) -C config/feature-checks clean >/dev/null
924 927
925clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean 928clean: $(LIBTRACEEVENT)-clean $(LIBAPIKFS)-clean config-clean
926 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS) 929 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS)
927 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf 930 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf
928 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* 931 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
929 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean 932 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c
index 9f870d27cb39..62eff847f91c 100644
--- a/tools/perf/arch/arm/tests/dwarf-unwind.c
+++ b/tools/perf/arch/arm/tests/dwarf-unwind.c
@@ -3,6 +3,7 @@
3#include "thread.h" 3#include "thread.h"
4#include "map.h" 4#include "map.h"
5#include "event.h" 5#include "event.h"
6#include "debug.h"
6#include "tests/tests.h" 7#include "tests/tests.h"
7 8
8#define STACK_SIZE 8192 9#define STACK_SIZE 8192
diff --git a/tools/perf/arch/arm/util/unwind-libunwind.c b/tools/perf/arch/arm/util/unwind-libunwind.c
index 729ed69a6664..62c397ed3d97 100644
--- a/tools/perf/arch/arm/util/unwind-libunwind.c
+++ b/tools/perf/arch/arm/util/unwind-libunwind.c
@@ -3,6 +3,7 @@
3#include <libunwind.h> 3#include <libunwind.h>
4#include "perf_regs.h" 4#include "perf_regs.h"
5#include "../../util/unwind.h" 5#include "../../util/unwind.h"
6#include "../../util/debug.h"
6 7
7int libunwind__arch_reg_id(int regnum) 8int libunwind__arch_reg_id(int regnum)
8{ 9{
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index b92219b1900d..6f7782bea5dd 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -1,6 +1,6 @@
1ifndef NO_DWARF 1ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1 2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o 3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o
4endif 5endif
5LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o 6LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
6LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/skip-callchain-idx.o
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
index 52a56599a543..d7f281c2828d 100644
--- a/tools/perf/bench/sched-messaging.c
+++ b/tools/perf/bench/sched-messaging.c
@@ -26,7 +26,7 @@
26#include <sys/socket.h> 26#include <sys/socket.h>
27#include <sys/wait.h> 27#include <sys/wait.h>
28#include <sys/time.h> 28#include <sys/time.h>
29#include <sys/poll.h> 29#include <poll.h>
30#include <limits.h> 30#include <limits.h>
31#include <err.h> 31#include <err.h>
32 32
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 1a4ef9cd9d5f..f5d3ae483110 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -543,14 +543,12 @@ static void print_vcpu_info(struct perf_kvm_stat *kvm)
543 543
544 pr_info("Analyze events for "); 544 pr_info("Analyze events for ");
545 545
546 if (kvm->live) { 546 if (kvm->opts.target.system_wide)
547 if (kvm->opts.target.system_wide) 547 pr_info("all VMs, ");
548 pr_info("all VMs, "); 548 else if (kvm->opts.target.pid)
549 else if (kvm->opts.target.pid) 549 pr_info("pid(s) %s, ", kvm->opts.target.pid);
550 pr_info("pid(s) %s, ", kvm->opts.target.pid); 550 else
551 else 551 pr_info("dazed and confused on what is monitored, ");
552 pr_info("dazed and confused on what is monitored, ");
553 }
554 552
555 if (vcpu == -1) 553 if (vcpu == -1)
556 pr_info("all VCPUs:\n\n"); 554 pr_info("all VCPUs:\n\n");
@@ -1085,8 +1083,8 @@ static int read_events(struct perf_kvm_stat *kvm)
1085 1083
1086static int parse_target_str(struct perf_kvm_stat *kvm) 1084static int parse_target_str(struct perf_kvm_stat *kvm)
1087{ 1085{
1088 if (kvm->pid_str) { 1086 if (kvm->opts.target.pid) {
1089 kvm->pid_list = intlist__new(kvm->pid_str); 1087 kvm->pid_list = intlist__new(kvm->opts.target.pid);
1090 if (kvm->pid_list == NULL) { 1088 if (kvm->pid_list == NULL) {
1091 pr_err("Error parsing process id string\n"); 1089 pr_err("Error parsing process id string\n");
1092 return -EINVAL; 1090 return -EINVAL;
@@ -1188,7 +1186,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1188 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1186 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
1189 "key for sorting: sample(sort by samples number)" 1187 "key for sorting: sample(sort by samples number)"
1190 " time (sort by avg time)"), 1188 " time (sort by avg time)"),
1191 OPT_STRING('p', "pid", &kvm->pid_str, "pid", 1189 OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
1192 "analyze events only for given process id(s)"), 1190 "analyze events only for given process id(s)"),
1193 OPT_END() 1191 OPT_END()
1194 }; 1192 };
@@ -1207,6 +1205,9 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1207 kvm_events_report_options); 1205 kvm_events_report_options);
1208 } 1206 }
1209 1207
1208 if (!kvm->opts.target.pid)
1209 kvm->opts.target.system_wide = true;
1210
1210 return kvm_events_report_vcpu(kvm); 1211 return kvm_events_report_vcpu(kvm);
1211} 1212}
1212 1213
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 347729e29a92..04412b4770a2 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -376,6 +376,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
376 "target executable name or path", opt_set_target), 376 "target executable name or path", opt_set_target),
377 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 377 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
378 "Disable symbol demangling"), 378 "Disable symbol demangling"),
379 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
380 "Enable kernel symbol demangling"),
379 OPT_END() 381 OPT_END()
380 }; 382 };
381 int ret; 383 int ret;
@@ -470,7 +472,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
470 usage_with_options(probe_usage, options); 472 usage_with_options(probe_usage, options);
471 } 473 }
472 474
473 ret = show_line_range(&params.line_range, params.target); 475 ret = show_line_range(&params.line_range, params.target,
476 params.uprobes);
474 if (ret < 0) 477 if (ret < 0)
475 pr_err_with_code(" Error: Failed to show lines.", ret); 478 pr_err_with_code(" Error: Failed to show lines.", ret);
476 return ret; 479 return ret;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 87e28a4e33ba..a1b040394170 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -65,8 +65,9 @@ static int process_synthesized_event(struct perf_tool *tool,
65 return record__write(rec, event, event->header.size); 65 return record__write(rec, event, event->header.size);
66} 66}
67 67
68static int record__mmap_read(struct record *rec, struct perf_mmap *md) 68static int record__mmap_read(struct record *rec, int idx)
69{ 69{
70 struct perf_mmap *md = &rec->evlist->mmap[idx];
70 unsigned int head = perf_mmap__read_head(md); 71 unsigned int head = perf_mmap__read_head(md);
71 unsigned int old = md->prev; 72 unsigned int old = md->prev;
72 unsigned char *data = md->base + page_size; 73 unsigned char *data = md->base + page_size;
@@ -102,8 +103,7 @@ static int record__mmap_read(struct record *rec, struct perf_mmap *md)
102 } 103 }
103 104
104 md->prev = old; 105 md->prev = old;
105 perf_mmap__write_tail(md, old); 106 perf_evlist__mmap_consume(rec->evlist, idx);
106
107out: 107out:
108 return rc; 108 return rc;
109} 109}
@@ -245,7 +245,7 @@ static int record__mmap_read_all(struct record *rec)
245 245
246 for (i = 0; i < rec->evlist->nr_mmaps; i++) { 246 for (i = 0; i < rec->evlist->nr_mmaps; i++) {
247 if (rec->evlist->mmap[i].base) { 247 if (rec->evlist->mmap[i].base) {
248 if (record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { 248 if (record__mmap_read(rec, i) != 0) {
249 rc = -1; 249 rc = -1;
250 goto out; 250 goto out;
251 } 251 }
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 3da59a87ec7c..8c0b3f22412a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -680,6 +680,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
680 "objdump binary to use for disassembly and annotations"), 680 "objdump binary to use for disassembly and annotations"),
681 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 681 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
682 "Disable symbol demangling"), 682 "Disable symbol demangling"),
683 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
684 "Enable kernel symbol demangling"),
683 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), 685 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
684 OPT_CALLBACK(0, "percent-limit", &report, "percent", 686 OPT_CALLBACK(0, "percent-limit", &report, "percent",
685 "Don't show entries under that percent", parse_percent_limit), 687 "Don't show entries under that percent", parse_percent_limit),
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 9848e270b92c..e13864be2acb 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -59,7 +59,7 @@
59 59
60#include <sys/syscall.h> 60#include <sys/syscall.h>
61#include <sys/ioctl.h> 61#include <sys/ioctl.h>
62#include <sys/poll.h> 62#include <poll.h>
63#include <sys/prctl.h> 63#include <sys/prctl.h>
64#include <sys/wait.h> 64#include <sys/wait.h>
65#include <sys/uio.h> 65#include <sys/uio.h>
@@ -1142,6 +1142,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1142 "Interleave source code with assembly code (default)"), 1142 "Interleave source code with assembly code (default)"),
1143 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw, 1143 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
1144 "Display raw encoding of assembly instructions (default)"), 1144 "Display raw encoding of assembly instructions (default)"),
1145 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1146 "Enable kernel symbol demangling"),
1145 OPT_STRING(0, "objdump", &objdump_path, "path", 1147 OPT_STRING(0, "objdump", &objdump_path, "path",
1146 "objdump binary to use for disassembly and annotations"), 1148 "objdump binary to use for disassembly and annotations"),
1147 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", 1149 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 75d4c237b03d..58f609198c6d 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -48,10 +48,6 @@ ifneq ($(ARCH),$(filter $(ARCH),x86 arm))
48 NO_LIBDW_DWARF_UNWIND := 1 48 NO_LIBDW_DWARF_UNWIND := 1
49endif 49endif
50 50
51ifeq ($(ARCH),powerpc)
52 CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX
53endif
54
55ifeq ($(LIBUNWIND_LIBS),) 51ifeq ($(LIBUNWIND_LIBS),)
56 NO_LIBUNWIND := 1 52 NO_LIBUNWIND := 1
57else 53else
@@ -378,6 +374,12 @@ ifndef NO_LIBELF
378 endif # NO_DWARF 374 endif # NO_DWARF
379endif # NO_LIBELF 375endif # NO_LIBELF
380 376
377ifeq ($(ARCH),powerpc)
378 ifndef NO_DWARF
379 CFLAGS += -DHAVE_SKIP_CALLCHAIN_IDX
380 endif
381endif
382
381ifndef NO_LIBUNWIND 383ifndef NO_LIBUNWIND
382 ifneq ($(feature-libunwind), 1) 384 ifneq ($(feature-libunwind), 1)
383 msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR); 385 msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
@@ -651,11 +653,13 @@ else
651sysconfdir = $(prefix)/etc 653sysconfdir = $(prefix)/etc
652ETC_PERFCONFIG = etc/perfconfig 654ETC_PERFCONFIG = etc/perfconfig
653endif 655endif
656ifndef lib
654ifeq ($(IS_X86_64),1) 657ifeq ($(IS_X86_64),1)
655lib = lib64 658lib = lib64
656else 659else
657lib = lib 660lib = lib
658endif 661endif
662endif # lib
659libdir = $(prefix)/$(lib) 663libdir = $(prefix)/$(lib)
660 664
661# Shell quote (do not use $(call) to accommodate ancient setups); 665# Shell quote (do not use $(call) to accommodate ancient setups);
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
index 4d985e0f03f5..7076a62d0ff7 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/perf/config/utilities.mak
@@ -132,7 +132,7 @@ endef
132# 132#
133# Usage: bool-value = $(call is-absolute,path) 133# Usage: bool-value = $(call is-absolute,path)
134# 134#
135is-absolute = $(shell echo $(shell-sq) | grep ^/ -q && echo y) 135is-absolute = $(shell echo $(shell-sq) | grep -q ^/ && echo y)
136 136
137# lookup 137# lookup
138# 138#
diff --git a/tools/perf/perf-with-kcore.sh b/tools/perf/perf-with-kcore.sh
new file mode 100644
index 000000000000..c7ff90a90e4e
--- /dev/null
+++ b/tools/perf/perf-with-kcore.sh
@@ -0,0 +1,259 @@
1#!/bin/bash
2# perf-with-kcore: use perf with a copy of kcore
3# Copyright (c) 2014, Intel Corporation.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms and conditions of the GNU General Public License,
7# version 2, as published by the Free Software Foundation.
8#
9# This program is distributed in the hope it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12# more details.
13
14set -e
15
16usage()
17{
18 echo "Usage: perf-with-kcore <perf sub-command> <perf.data directory> [<sub-command options> [ -- <workload>]]" >&2
19 echo " <perf sub-command> can be record, script, report or inject" >&2
20 echo " or: perf-with-kcore fix_buildid_cache_permissions" >&2
21 exit 1
22}
23
24find_perf()
25{
26 if [ -n "$PERF" ] ; then
27 return
28 fi
29 PERF=`which perf || true`
30 if [ -z "$PERF" ] ; then
31 echo "Failed to find perf" >&2
32 exit 1
33 fi
34 if [ ! -x "$PERF" ] ; then
35 echo "Failed to find perf" >&2
36 exit 1
37 fi
38 echo "Using $PERF"
39 "$PERF" version
40}
41
42copy_kcore()
43{
44 echo "Copying kcore"
45
46 if [ $EUID -eq 0 ] ; then
47 SUDO=""
48 else
49 SUDO="sudo"
50 fi
51
52 rm -f perf.data.junk
53 ("$PERF" record -o perf.data.junk $PERF_OPTIONS -- sleep 60) >/dev/null 2>/dev/null &
54 PERF_PID=$!
55
56 # Need to make sure that perf has started
57 sleep 1
58
59 KCORE=$(($SUDO "$PERF" buildid-cache -v -f -k /proc/kcore >/dev/null) 2>&1)
60 case "$KCORE" in
61 "kcore added to build-id cache directory "*)
62 KCORE_DIR=${KCORE#"kcore added to build-id cache directory "}
63 ;;
64 *)
65 kill $PERF_PID
66 wait >/dev/null 2>/dev/null || true
67 rm perf.data.junk
68 echo "$KCORE"
69 echo "Failed to find kcore" >&2
70 exit 1
71 ;;
72 esac
73
74 kill $PERF_PID
75 wait >/dev/null 2>/dev/null || true
76 rm perf.data.junk
77
78 $SUDO cp -a "$KCORE_DIR" "$(pwd)/$PERF_DATA_DIR"
79 $SUDO rm -f "$KCORE_DIR/kcore"
80 $SUDO rm -f "$KCORE_DIR/kallsyms"
81 $SUDO rm -f "$KCORE_DIR/modules"
82 $SUDO rmdir "$KCORE_DIR"
83
84 KCORE_DIR_BASENAME=$(basename "$KCORE_DIR")
85 KCORE_DIR="$(pwd)/$PERF_DATA_DIR/$KCORE_DIR_BASENAME"
86
87 $SUDO chown $UID "$KCORE_DIR"
88 $SUDO chown $UID "$KCORE_DIR/kcore"
89 $SUDO chown $UID "$KCORE_DIR/kallsyms"
90 $SUDO chown $UID "$KCORE_DIR/modules"
91
92 $SUDO chgrp $GROUPS "$KCORE_DIR"
93 $SUDO chgrp $GROUPS "$KCORE_DIR/kcore"
94 $SUDO chgrp $GROUPS "$KCORE_DIR/kallsyms"
95 $SUDO chgrp $GROUPS "$KCORE_DIR/modules"
96
97 ln -s "$KCORE_DIR_BASENAME" "$PERF_DATA_DIR/kcore_dir"
98}
99
100fix_buildid_cache_permissions()
101{
102 if [ $EUID -ne 0 ] ; then
103 echo "This script must be run as root via sudo " >&2
104 exit 1
105 fi
106
107 if [ -z "$SUDO_USER" ] ; then
108 echo "This script must be run via sudo" >&2
109 exit 1
110 fi
111
112 USER_HOME=$(bash <<< "echo ~$SUDO_USER")
113
114 if [ "$HOME" != "$USER_HOME" ] ; then
115 echo "Fix unnecessary because root has a home: $HOME" >&2
116 exit 1
117 fi
118
119 echo "Fixing buildid cache permissions"
120
121 find "$USER_HOME/.debug" -xdev -type d ! -user "$SUDO_USER" -ls -exec chown "$SUDO_USER" \{\} \;
122 find "$USER_HOME/.debug" -xdev -type f -links 1 ! -user "$SUDO_USER" -ls -exec chown "$SUDO_USER" \{\} \;
123 find "$USER_HOME/.debug" -xdev -type l ! -user "$SUDO_USER" -ls -exec chown -h "$SUDO_USER" \{\} \;
124
125 if [ -n "$SUDO_GID" ] ; then
126 find "$USER_HOME/.debug" -xdev -type d ! -group "$SUDO_GID" -ls -exec chgrp "$SUDO_GID" \{\} \;
127 find "$USER_HOME/.debug" -xdev -type f -links 1 ! -group "$SUDO_GID" -ls -exec chgrp "$SUDO_GID" \{\} \;
128 find "$USER_HOME/.debug" -xdev -type l ! -group "$SUDO_GID" -ls -exec chgrp -h "$SUDO_GID" \{\} \;
129 fi
130
131 echo "Done"
132}
133
134check_buildid_cache_permissions()
135{
136 if [ $EUID -eq 0 ] ; then
137 return
138 fi
139
140 PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type d ! -user "$USER" -print -quit)
141 PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type f -links 1 ! -user "$USER" -print -quit)
142 PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type l ! -user "$USER" -print -quit)
143
144 PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type d ! -group "$GROUPS" -print -quit)
145 PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type f -links 1 ! -group "$GROUPS" -print -quit)
146 PERMISSIONS_OK+=$(find "$HOME/.debug" -xdev -type l ! -group "$GROUPS" -print -quit)
147
148 if [ -n "$PERMISSIONS_OK" ] ; then
149 echo "*** WARNING *** buildid cache permissions may need fixing" >&2
150 fi
151}
152
153record()
154{
155 echo "Recording"
156
157 if [ $EUID -ne 0 ] ; then
158
159 if [ "$(cat /proc/sys/kernel/kptr_restrict)" -ne 0 ] ; then
160 echo "*** WARNING *** /proc/sys/kernel/kptr_restrict prevents access to kernel addresses" >&2
161 fi
162
163 if echo "$PERF_OPTIONS" | grep -q ' -a \|^-a \| -a$\|^-a$\| --all-cpus \|^--all-cpus \| --all-cpus$\|^--all-cpus$' ; then
164 echo "*** WARNING *** system-wide tracing without root access will not be able to read all necessary information from /proc" >&2
165 fi
166
167 if echo "$PERF_OPTIONS" | grep -q 'intel_pt\|intel_bts\| -I\|^-I' ; then
168 if [ "$(cat /proc/sys/kernel/perf_event_paranoid)" -gt -1 ] ; then
169 echo "*** WARNING *** /proc/sys/kernel/perf_event_paranoid restricts buffer size and tracepoint (sched_switch) use" >&2
170 fi
171
172 if echo "$PERF_OPTIONS" | grep -q ' --per-thread \|^--per-thread \| --per-thread$\|^--per-thread$' ; then
173 true
174 elif echo "$PERF_OPTIONS" | grep -q ' -t \|^-t \| -t$\|^-t$' ; then
175 true
176 elif [ ! -r /sys/kernel/debug -o ! -x /sys/kernel/debug ] ; then
177 echo "*** WARNING *** /sys/kernel/debug permissions prevent tracepoint (sched_switch) use" >&2
178 fi
179 fi
180 fi
181
182 if [ -z "$1" ] ; then
183 echo "Workload is required for recording" >&2
184 usage
185 fi
186
187 if [ -e "$PERF_DATA_DIR" ] ; then
188 echo "'$PERF_DATA_DIR' exists" >&2
189 exit 1
190 fi
191
192 find_perf
193
194 mkdir "$PERF_DATA_DIR"
195
196 echo "$PERF record -o $PERF_DATA_DIR/perf.data $PERF_OPTIONS -- $*"
197 "$PERF" record -o "$PERF_DATA_DIR/perf.data" $PERF_OPTIONS -- $* || true
198
199 if rmdir "$PERF_DATA_DIR" > /dev/null 2>/dev/null ; then
200 exit 1
201 fi
202
203 copy_kcore
204
205 echo "Done"
206}
207
208subcommand()
209{
210 find_perf
211 check_buildid_cache_permissions
212 echo "$PERF $PERF_SUB_COMMAND -i $PERF_DATA_DIR/perf.data --kallsyms=$PERF_DATA_DIR/kcore_dir/kallsyms $*"
213 "$PERF" $PERF_SUB_COMMAND -i "$PERF_DATA_DIR/perf.data" "--kallsyms=$PERF_DATA_DIR/kcore_dir/kallsyms" $*
214}
215
216if [ "$1" = "fix_buildid_cache_permissions" ] ; then
217 fix_buildid_cache_permissions
218 exit 0
219fi
220
221PERF_SUB_COMMAND=$1
222PERF_DATA_DIR=$2
223shift || true
224shift || true
225
226if [ -z "$PERF_SUB_COMMAND" ] ; then
227 usage
228fi
229
230if [ -z "$PERF_DATA_DIR" ] ; then
231 usage
232fi
233
234case "$PERF_SUB_COMMAND" in
235"record")
236 while [ "$1" != "--" ] ; do
237 PERF_OPTIONS+="$1 "
238 shift || break
239 done
240 if [ "$1" != "--" ] ; then
241 echo "Options and workload are required for recording" >&2
242 usage
243 fi
244 shift
245 record $*
246;;
247"script")
248 subcommand $*
249;;
250"report")
251 subcommand $*
252;;
253"inject")
254 subcommand $*
255;;
256*)
257 usage
258;;
259esac
diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
index 12b322fa3475..eeb68bb1972d 100644
--- a/tools/perf/tests/pmu.c
+++ b/tools/perf/tests/pmu.c
@@ -152,7 +152,7 @@ int test__pmu(void)
152 if (ret) 152 if (ret)
153 break; 153 break;
154 154
155 ret = perf_pmu__config_terms(&formats, &attr, terms); 155 ret = perf_pmu__config_terms(&formats, &attr, terms, false);
156 if (ret) 156 if (ret)
157 break; 157 break;
158 158
diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h
index 0b5a8cd2ee79..cf1d7913783b 100644
--- a/tools/perf/util/kvm-stat.h
+++ b/tools/perf/util/kvm-stat.h
@@ -92,7 +92,6 @@ struct perf_kvm_stat {
92 u64 lost_events; 92 u64 lost_events;
93 u64 duration; 93 u64 duration;
94 94
95 const char *pid_str;
96 struct intlist *pid_list; 95 struct intlist *pid_list;
97 96
98 struct rb_root result; 97 struct rb_root result;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index e34c81a0bcf3..61be3e695ec2 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -643,7 +643,18 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
643 if (!pmu) 643 if (!pmu)
644 return -EINVAL; 644 return -EINVAL;
645 645
646 memset(&attr, 0, sizeof(attr)); 646 if (pmu->default_config) {
647 memcpy(&attr, pmu->default_config,
648 sizeof(struct perf_event_attr));
649 } else {
650 memset(&attr, 0, sizeof(attr));
651 }
652
653 if (!head_config) {
654 attr.type = pmu->type;
655 evsel = __add_event(list, idx, &attr, NULL, pmu->cpus);
656 return evsel ? 0 : -ENOMEM;
657 }
647 658
648 if (perf_pmu__check_alias(pmu, head_config, &unit, &scale)) 659 if (perf_pmu__check_alias(pmu, head_config, &unit, &scale))
649 return -EINVAL; 660 return -EINVAL;
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 0bc87ba46bf3..55fab6ad609a 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -210,6 +210,16 @@ PE_NAME '/' event_config '/'
210 parse_events__free_terms($3); 210 parse_events__free_terms($3);
211 $$ = list; 211 $$ = list;
212} 212}
213|
214PE_NAME '/' '/'
215{
216 struct parse_events_evlist *data = _data;
217 struct list_head *list;
218
219 ALLOC_LIST(list);
220 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL));
221 $$ = list;
222}
213 223
214value_sym: 224value_sym:
215PE_VALUE_SYM_HW 225PE_VALUE_SYM_HW
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 9bf582750561..22a4ad5a927a 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -2,6 +2,8 @@
2#include <sys/types.h> 2#include <sys/types.h>
3#include <unistd.h> 3#include <unistd.h>
4#include <stdio.h> 4#include <stdio.h>
5#include <stdbool.h>
6#include <stdarg.h>
5#include <dirent.h> 7#include <dirent.h>
6#include <api/fs/fs.h> 8#include <api/fs/fs.h>
7#include <locale.h> 9#include <locale.h>
@@ -387,6 +389,12 @@ static struct cpu_map *pmu_cpumask(const char *name)
387 return cpus; 389 return cpus;
388} 390}
389 391
392struct perf_event_attr *__attribute__((weak))
393perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
394{
395 return NULL;
396}
397
390static struct perf_pmu *pmu_lookup(const char *name) 398static struct perf_pmu *pmu_lookup(const char *name)
391{ 399{
392 struct perf_pmu *pmu; 400 struct perf_pmu *pmu;
@@ -421,6 +429,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
421 pmu->name = strdup(name); 429 pmu->name = strdup(name);
422 pmu->type = type; 430 pmu->type = type;
423 list_add_tail(&pmu->list, &pmus); 431 list_add_tail(&pmu->list, &pmus);
432
433 pmu->default_config = perf_pmu__get_default_config(pmu);
434
424 return pmu; 435 return pmu;
425} 436}
426 437
@@ -479,28 +490,24 @@ pmu_find_format(struct list_head *formats, char *name)
479} 490}
480 491
481/* 492/*
482 * Returns value based on the format definition (format parameter) 493 * Sets value based on the format definition (format parameter)
483 * and unformated value (value parameter). 494 * and unformated value (value parameter).
484 *
485 * TODO maybe optimize a little ;)
486 */ 495 */
487static __u64 pmu_format_value(unsigned long *format, __u64 value) 496static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
497 bool zero)
488{ 498{
489 unsigned long fbit, vbit; 499 unsigned long fbit, vbit;
490 __u64 v = 0;
491 500
492 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { 501 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
493 502
494 if (!test_bit(fbit, format)) 503 if (!test_bit(fbit, format))
495 continue; 504 continue;
496 505
497 if (!(value & (1llu << vbit++))) 506 if (value & (1llu << vbit++))
498 continue; 507 *v |= (1llu << fbit);
499 508 else if (zero)
500 v |= (1llu << fbit); 509 *v &= ~(1llu << fbit);
501 } 510 }
502
503 return v;
504} 511}
505 512
506/* 513/*
@@ -509,7 +516,8 @@ static __u64 pmu_format_value(unsigned long *format, __u64 value)
509 */ 516 */
510static int pmu_config_term(struct list_head *formats, 517static int pmu_config_term(struct list_head *formats,
511 struct perf_event_attr *attr, 518 struct perf_event_attr *attr,
512 struct parse_events_term *term) 519 struct parse_events_term *term,
520 bool zero)
513{ 521{
514 struct perf_pmu_format *format; 522 struct perf_pmu_format *format;
515 __u64 *vp; 523 __u64 *vp;
@@ -548,18 +556,19 @@ static int pmu_config_term(struct list_head *formats,
548 * non-hardcoded terms, here's the place to translate 556 * non-hardcoded terms, here's the place to translate
549 * them into value. 557 * them into value.
550 */ 558 */
551 *vp |= pmu_format_value(format->bits, term->val.num); 559 pmu_format_value(format->bits, term->val.num, vp, zero);
552 return 0; 560 return 0;
553} 561}
554 562
555int perf_pmu__config_terms(struct list_head *formats, 563int perf_pmu__config_terms(struct list_head *formats,
556 struct perf_event_attr *attr, 564 struct perf_event_attr *attr,
557 struct list_head *head_terms) 565 struct list_head *head_terms,
566 bool zero)
558{ 567{
559 struct parse_events_term *term; 568 struct parse_events_term *term;
560 569
561 list_for_each_entry(term, head_terms, list) 570 list_for_each_entry(term, head_terms, list)
562 if (pmu_config_term(formats, attr, term)) 571 if (pmu_config_term(formats, attr, term, zero))
563 return -EINVAL; 572 return -EINVAL;
564 573
565 return 0; 574 return 0;
@@ -573,8 +582,10 @@ int perf_pmu__config_terms(struct list_head *formats,
573int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 582int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
574 struct list_head *head_terms) 583 struct list_head *head_terms)
575{ 584{
585 bool zero = !!pmu->default_config;
586
576 attr->type = pmu->type; 587 attr->type = pmu->type;
577 return perf_pmu__config_terms(&pmu->format, attr, head_terms); 588 return perf_pmu__config_terms(&pmu->format, attr, head_terms, zero);
578} 589}
579 590
580static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, 591static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
@@ -794,3 +805,39 @@ bool pmu_have_event(const char *pname, const char *name)
794 } 805 }
795 return false; 806 return false;
796} 807}
808
809static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
810{
811 struct stat st;
812 char path[PATH_MAX];
813 const char *sysfs;
814
815 sysfs = sysfs__mountpoint();
816 if (!sysfs)
817 return NULL;
818
819 snprintf(path, PATH_MAX,
820 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
821
822 if (stat(path, &st) < 0)
823 return NULL;
824
825 return fopen(path, "r");
826}
827
828int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
829 ...)
830{
831 va_list args;
832 FILE *file;
833 int ret = EOF;
834
835 va_start(args, fmt);
836 file = perf_pmu__open_file(pmu, name);
837 if (file) {
838 ret = vfscanf(file, fmt, args);
839 fclose(file);
840 }
841 va_end(args);
842 return ret;
843}
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 1c1e2eecbe1f..0f5c0a88fdc8 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -13,9 +13,12 @@ enum {
13 13
14#define PERF_PMU_FORMAT_BITS 64 14#define PERF_PMU_FORMAT_BITS 64
15 15
16struct perf_event_attr;
17
16struct perf_pmu { 18struct perf_pmu {
17 char *name; 19 char *name;
18 __u32 type; 20 __u32 type;
21 struct perf_event_attr *default_config;
19 struct cpu_map *cpus; 22 struct cpu_map *cpus;
20 struct list_head format; /* HEAD struct perf_pmu_format -> list */ 23 struct list_head format; /* HEAD struct perf_pmu_format -> list */
21 struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ 24 struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */
@@ -27,7 +30,8 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
27 struct list_head *head_terms); 30 struct list_head *head_terms);
28int perf_pmu__config_terms(struct list_head *formats, 31int perf_pmu__config_terms(struct list_head *formats,
29 struct perf_event_attr *attr, 32 struct perf_event_attr *attr,
30 struct list_head *head_terms); 33 struct list_head *head_terms,
34 bool zero);
31int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, 35int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
32 const char **unit, double *scale); 36 const char **unit, double *scale);
33struct list_head *perf_pmu__alias(struct perf_pmu *pmu, 37struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
@@ -45,5 +49,11 @@ struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
45void print_pmu_events(const char *event_glob, bool name_only); 49void print_pmu_events(const char *event_glob, bool name_only);
46bool pmu_have_event(const char *pname, const char *name); 50bool pmu_have_event(const char *pname, const char *name);
47 51
52int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
53 ...) __attribute__((format(scanf, 3, 4)));
54
48int perf_pmu__test(void); 55int perf_pmu__test(void);
56
57struct perf_event_attr *perf_pmu__get_default_config(struct perf_pmu *pmu);
58
49#endif /* __PMU_H */ 59#endif /* __PMU_H */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f73595fc0627..be37b5aca335 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -697,11 +697,11 @@ end:
697 return ret; 697 return ret;
698} 698}
699 699
700int show_line_range(struct line_range *lr, const char *module) 700int show_line_range(struct line_range *lr, const char *module, bool user)
701{ 701{
702 int ret; 702 int ret;
703 703
704 ret = init_symbol_maps(false); 704 ret = init_symbol_maps(user);
705 if (ret < 0) 705 if (ret < 0)
706 return ret; 706 return ret;
707 ret = __show_line_range(lr, module); 707 ret = __show_line_range(lr, module);
@@ -776,7 +776,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
776 int i, ret = 0; 776 int i, ret = 0;
777 struct debuginfo *dinfo; 777 struct debuginfo *dinfo;
778 778
779 ret = init_symbol_maps(false); 779 ret = init_symbol_maps(pevs->uprobes);
780 if (ret < 0) 780 if (ret < 0)
781 return ret; 781 return ret;
782 782
@@ -822,7 +822,8 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
822} 822}
823 823
824int show_line_range(struct line_range *lr __maybe_unused, 824int show_line_range(struct line_range *lr __maybe_unused,
825 const char *module __maybe_unused) 825 const char *module __maybe_unused,
826 bool user __maybe_unused)
826{ 827{
827 pr_warning("Debuginfo-analysis is not supported.\n"); 828 pr_warning("Debuginfo-analysis is not supported.\n");
828 return -ENOSYS; 829 return -ENOSYS;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 776c9347a3b6..e01e9943139f 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -128,7 +128,8 @@ extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
128 bool force_add); 128 bool force_add);
129extern int del_perf_probe_events(struct strlist *dellist); 129extern int del_perf_probe_events(struct strlist *dellist);
130extern int show_perf_probe_events(void); 130extern int show_perf_probe_events(void);
131extern int show_line_range(struct line_range *lr, const char *module); 131extern int show_line_range(struct line_range *lr, const char *module,
132 bool user);
132extern int show_available_vars(struct perf_probe_event *pevs, int npevs, 133extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
133 int max_probe_points, const char *module, 134 int max_probe_points, const char *module,
134 struct strfilter *filter, bool externs); 135 struct strfilter *filter, bool externs);
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 9c593561aa71..c7918f83b300 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -609,14 +609,18 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
609 return -EINVAL; 609 return -EINVAL;
610 } 610 }
611 611
612 /* Get an appropriate symbol from symtab */ 612 symbol = dwarf_diename(sp_die);
613 symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
614 if (!symbol) { 613 if (!symbol) {
615 pr_warning("Failed to find symbol at 0x%lx\n", 614 /* Try to get the symbol name from symtab */
616 (unsigned long)paddr); 615 symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
617 return -ENOENT; 616 if (!symbol) {
617 pr_warning("Failed to find symbol at 0x%lx\n",
618 (unsigned long)paddr);
619 return -ENOENT;
620 }
621 eaddr = sym.st_value;
618 } 622 }
619 tp->offset = (unsigned long)(paddr - sym.st_value); 623 tp->offset = (unsigned long)(paddr - eaddr);
620 tp->address = (unsigned long)paddr; 624 tp->address = (unsigned long)paddr;
621 tp->symbol = strdup(symbol); 625 tp->symbol = strdup(symbol);
622 if (!tp->symbol) 626 if (!tp->symbol)
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 1958637cf136..289df9d1e65a 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1446,12 +1446,47 @@ static const char *get_default_sort_order(void)
1446 return default_sort_orders[sort__mode]; 1446 return default_sort_orders[sort__mode];
1447} 1447}
1448 1448
1449static int setup_sort_order(void)
1450{
1451 char *new_sort_order;
1452
1453 /*
1454 * Append '+'-prefixed sort order to the default sort
1455 * order string.
1456 */
1457 if (!sort_order || is_strict_order(sort_order))
1458 return 0;
1459
1460 if (sort_order[1] == '\0') {
1461 error("Invalid --sort key: `+'");
1462 return -EINVAL;
1463 }
1464
1465 /*
1466 * We allocate new sort_order string, but we never free it,
1467 * because it's checked over the rest of the code.
1468 */
1469 if (asprintf(&new_sort_order, "%s,%s",
1470 get_default_sort_order(), sort_order + 1) < 0) {
1471 error("Not enough memory to set up --sort");
1472 return -ENOMEM;
1473 }
1474
1475 sort_order = new_sort_order;
1476 return 0;
1477}
1478
1449static int __setup_sorting(void) 1479static int __setup_sorting(void)
1450{ 1480{
1451 char *tmp, *tok, *str; 1481 char *tmp, *tok, *str;
1452 const char *sort_keys = sort_order; 1482 const char *sort_keys;
1453 int ret = 0; 1483 int ret = 0;
1454 1484
1485 ret = setup_sort_order();
1486 if (ret)
1487 return ret;
1488
1489 sort_keys = sort_order;
1455 if (sort_keys == NULL) { 1490 if (sort_keys == NULL) {
1456 if (is_strict_order(field_order)) { 1491 if (is_strict_order(field_order)) {
1457 /* 1492 /*
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 9fb5e9e9f161..2a92e10317c5 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -680,6 +680,11 @@ static u64 ref_reloc(struct kmap *kmap)
680 return 0; 680 return 0;
681} 681}
682 682
683static bool want_demangle(bool is_kernel_sym)
684{
685 return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
686}
687
683int dso__load_sym(struct dso *dso, struct map *map, 688int dso__load_sym(struct dso *dso, struct map *map,
684 struct symsrc *syms_ss, struct symsrc *runtime_ss, 689 struct symsrc *syms_ss, struct symsrc *runtime_ss,
685 symbol_filter_t filter, int kmodule) 690 symbol_filter_t filter, int kmodule)
@@ -712,6 +717,14 @@ int dso__load_sym(struct dso *dso, struct map *map,
712 symbols__delete(&dso->symbols[map->type]); 717 symbols__delete(&dso->symbols[map->type]);
713 718
714 if (!syms_ss->symtab) { 719 if (!syms_ss->symtab) {
720 /*
721 * If the vmlinux is stripped, fail so we will fall back
722 * to using kallsyms. The vmlinux runtime symbols aren't
723 * of much use.
724 */
725 if (dso->kernel)
726 goto out_elf_end;
727
715 syms_ss->symtab = syms_ss->dynsym; 728 syms_ss->symtab = syms_ss->dynsym;
716 syms_ss->symshdr = syms_ss->dynshdr; 729 syms_ss->symshdr = syms_ss->dynshdr;
717 } 730 }
@@ -938,7 +951,7 @@ new_symbol:
938 * DWARF DW_compile_unit has this, but we don't always have access 951 * DWARF DW_compile_unit has this, but we don't always have access
939 * to it... 952 * to it...
940 */ 953 */
941 if (symbol_conf.demangle) { 954 if (want_demangle(dso->kernel || kmodule)) {
942 int demangle_flags = DMGL_NO_OPTS; 955 int demangle_flags = DMGL_NO_OPTS;
943 if (verbose) 956 if (verbose)
944 demangle_flags = DMGL_PARAMS | DMGL_ANSI; 957 demangle_flags = DMGL_PARAMS | DMGL_ANSI;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ac098a3c2a31..be84f7a9838b 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -34,6 +34,7 @@ struct symbol_conf symbol_conf = {
34 .try_vmlinux_path = true, 34 .try_vmlinux_path = true,
35 .annotate_src = true, 35 .annotate_src = true,
36 .demangle = true, 36 .demangle = true,
37 .demangle_kernel = false,
37 .cumulate_callchain = true, 38 .cumulate_callchain = true,
38 .show_hist_headers = true, 39 .show_hist_headers = true,
39 .symfs = "", 40 .symfs = "",
@@ -1756,7 +1757,7 @@ static int vmlinux_path__init(struct perf_session_env *env)
1756 char bf[PATH_MAX]; 1757 char bf[PATH_MAX];
1757 char *kernel_version; 1758 char *kernel_version;
1758 1759
1759 vmlinux_path = malloc(sizeof(char *) * 5); 1760 vmlinux_path = malloc(sizeof(char *) * 6);
1760 if (vmlinux_path == NULL) 1761 if (vmlinux_path == NULL)
1761 return -1; 1762 return -1;
1762 1763
@@ -1787,6 +1788,12 @@ static int vmlinux_path__init(struct perf_session_env *env)
1787 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1788 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1788 goto out_fail; 1789 goto out_fail;
1789 ++vmlinux_path__nr_entries; 1790 ++vmlinux_path__nr_entries;
1791 snprintf(bf, sizeof(bf), "/usr/lib/debug/boot/vmlinux-%s",
1792 kernel_version);
1793 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1794 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1795 goto out_fail;
1796 ++vmlinux_path__nr_entries;
1790 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version); 1797 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version);
1791 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1798 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1792 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1799 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 3f95ea0357e3..bec4b7bd09de 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -120,6 +120,7 @@ struct symbol_conf {
120 annotate_src, 120 annotate_src,
121 event_group, 121 event_group,
122 demangle, 122 demangle,
123 demangle_kernel,
123 filter_relative, 124 filter_relative,
124 show_hist_headers; 125 show_hist_headers;
125 const char *vmlinux_name, 126 const char *vmlinux_name,
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index d6a79b1fb28c..80bfdaa0e2a4 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -39,6 +39,8 @@
39 39
40#define _ALL_SOURCE 1 40#define _ALL_SOURCE 1
41#define _BSD_SOURCE 1 41#define _BSD_SOURCE 1
42/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */
43#define _DEFAULT_SOURCE 1
42#define HAS_BOOL 44#define HAS_BOOL
43 45
44#include <unistd.h> 46#include <unistd.h>
@@ -64,7 +66,7 @@
64#include <regex.h> 66#include <regex.h>
65#include <utime.h> 67#include <utime.h>
66#include <sys/wait.h> 68#include <sys/wait.h>
67#include <sys/poll.h> 69#include <poll.h>
68#include <sys/socket.h> 70#include <sys/socket.h>
69#include <sys/ioctl.h> 71#include <sys/ioctl.h>
70#include <inttypes.h> 72#include <inttypes.h>