aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-11-20 02:32:01 -0500
committerIngo Molnar <mingo@kernel.org>2014-11-20 02:32:01 -0500
commit4e6e311e596eadba30d4f56f64eae7d45611a01c (patch)
tree681fb4c9ae7320ab1192f92e1c153ab35c90bf8e
parent2565711fb7d7c28e0cd93c8971b520d1b10b857c (diff)
parenta84808083688d82d7f1e5786ccf5df0ff7d448cb (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 fixes: - Fallback to kallsyms when using the minimal 'ELF' loader (Arnaldo Carvalho de Melo) - Fix annotation with kcore (Adrian Hunter) - Fix up srcline histogram key formatting (Arnaldo Carvalho de Melo) - Add missing handler for PERF_RECORD_MMAP2 events in 'perf diff' (Kan Liang) User visible changes/new features: - Only print base source file for srcline histogram sort key (Andi Kleen) - Support source line numbers in annotate using a hotkey (Andi Kleen) Infrastructure changes and fixes: - Do not poll events that use the system_wide flag (Adrian Hunter) - Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore (Adrian Hunter) - Only override the default :tid comm entry (Adrian Hunter) - Factor out adding new call chain entries (Andi Kleen) - Use al.addr to set up call chain (Andi Kleen) - Use a common function to resolve symbol or name (Andi Kleen) - Fix ftrace:function event recording (Jiri Olsa) - Move disable_buildid_cache() to util/build-id.c (Namhyung Kim) - Clean up libelf feature support code (Namhyung Kim) - Fix typo in python 'perf test' (WANG Chao) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/perf/.gitignore2
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/builtin-diff.c1
-rw-r--r--tools/perf/config/Makefile5
-rw-r--r--tools/perf/tests/builtin-test.c2
-rw-r--r--tools/perf/ui/browsers/annotate.c13
-rw-r--r--tools/perf/ui/browsers/hists.c17
-rw-r--r--tools/perf/ui/gtk/hists.c11
-rw-r--r--tools/perf/ui/stdio/hist.c23
-rw-r--r--tools/perf/util/annotate.c32
-rw-r--r--tools/perf/util/annotate.h1
-rw-r--r--tools/perf/util/build-id.c11
-rw-r--r--tools/perf/util/build-id.h1
-rw-r--r--tools/perf/util/callchain.c19
-rw-r--r--tools/perf/util/callchain.h3
-rw-r--r--tools/perf/util/evlist.c10
-rw-r--r--tools/perf/util/evsel.c8
-rw-r--r--tools/perf/util/header.c10
-rw-r--r--tools/perf/util/machine.c51
-rw-r--r--tools/perf/util/sort.c2
-rw-r--r--tools/perf/util/srcline.c2
-rw-r--r--tools/perf/util/symbol-minimal.c1
-rw-r--r--tools/perf/util/thread.c5
-rw-r--r--tools/perf/util/util.h1
24 files changed, 145 insertions, 88 deletions
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 717221e98450..40399c3d97d6 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -2,6 +2,8 @@ PERF-CFLAGS
2PERF-GUI-VARS 2PERF-GUI-VARS
3PERF-VERSION-FILE 3PERF-VERSION-FILE
4perf 4perf
5perf-read-vdso32
6perf-read-vdsox32
5perf-help 7perf-help
6perf-record 8perf-record
7perf-report 9perf-report
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index aecf61dcd754..478efa9b2364 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -497,8 +497,6 @@ ifneq ($(OUTPUT),)
497endif 497endif
498 498
499ifdef NO_LIBELF 499ifdef NO_LIBELF
500EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
501
502# Remove ELF/DWARF dependent codes 500# Remove ELF/DWARF dependent codes
503LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS)) 501LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS))
504LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS)) 502LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 25114c9a6801..1ce425d101a9 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -357,6 +357,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
357static struct perf_tool tool = { 357static struct perf_tool tool = {
358 .sample = diff__process_sample_event, 358 .sample = diff__process_sample_event,
359 .mmap = perf_event__process_mmap, 359 .mmap = perf_event__process_mmap,
360 .mmap2 = perf_event__process_mmap2,
360 .comm = perf_event__process_comm, 361 .comm = perf_event__process_comm,
361 .exit = perf_event__process_exit, 362 .exit = perf_event__process_exit,
362 .fork = perf_event__process_fork, 363 .fork = perf_event__process_fork,
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 79f906c7124e..5d4b039fe1ed 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -150,7 +150,7 @@ CFLAGS += -std=gnu99
150# adding assembler files missing the .GNU-stack linker note. 150# adding assembler files missing the .GNU-stack linker note.
151LDFLAGS += -Wl,-z,noexecstack 151LDFLAGS += -Wl,-z,noexecstack
152 152
153EXTLIBS = -lelf -lpthread -lrt -lm -ldl 153EXTLIBS = -lpthread -lrt -lm -ldl
154 154
155ifneq ($(OUTPUT),) 155ifneq ($(OUTPUT),)
156 OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/ 156 OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
@@ -354,6 +354,7 @@ endif # NO_LIBELF
354 354
355ifndef NO_LIBELF 355ifndef NO_LIBELF
356 CFLAGS += -DHAVE_LIBELF_SUPPORT 356 CFLAGS += -DHAVE_LIBELF_SUPPORT
357 EXTLIBS += -lelf
357 358
358 ifeq ($(feature-libelf-mmap), 1) 359 ifeq ($(feature-libelf-mmap), 1)
359 CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT 360 CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
@@ -373,7 +374,7 @@ ifndef NO_LIBELF
373 else 374 else
374 CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) 375 CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS)
375 LDFLAGS += $(LIBDW_LDFLAGS) 376 LDFLAGS += $(LIBDW_LDFLAGS)
376 EXTLIBS += -lelf -ldw 377 EXTLIBS += -ldw
377 endif # PERF_HAVE_DWARF_REGS 378 endif # PERF_HAVE_DWARF_REGS
378 endif # NO_DWARF 379 endif # NO_DWARF
379endif # NO_LIBELF 380endif # NO_LIBELF
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 162c978f1491..4b7d9ab0f049 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -85,7 +85,7 @@ static struct test {
85 .func = test__hists_link, 85 .func = test__hists_link,
86 }, 86 },
87 { 87 {
88 .desc = "Try 'use perf' in python, checking link problems", 88 .desc = "Try 'import perf' in python, checking link problems",
89 .func = test__python_use, 89 .func = test__python_use,
90 }, 90 },
91 { 91 {
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index f0697a3aede0..1e0a2fd80115 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -27,6 +27,7 @@ static struct annotate_browser_opt {
27 bool hide_src_code, 27 bool hide_src_code,
28 use_offset, 28 use_offset,
29 jump_arrows, 29 jump_arrows,
30 show_linenr,
30 show_nr_jumps; 31 show_nr_jumps;
31} annotate_browser__opts = { 32} annotate_browser__opts = {
32 .use_offset = true, 33 .use_offset = true,
@@ -128,7 +129,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
128 if (!*dl->line) 129 if (!*dl->line)
129 slsmg_write_nstring(" ", width - pcnt_width); 130 slsmg_write_nstring(" ", width - pcnt_width);
130 else if (dl->offset == -1) { 131 else if (dl->offset == -1) {
131 printed = scnprintf(bf, sizeof(bf), "%*s ", 132 if (dl->line_nr && annotate_browser__opts.show_linenr)
133 printed = scnprintf(bf, sizeof(bf), "%-*d ",
134 ab->addr_width + 1, dl->line_nr);
135 else
136 printed = scnprintf(bf, sizeof(bf), "%*s ",
132 ab->addr_width, " "); 137 ab->addr_width, " ");
133 slsmg_write_nstring(bf, printed); 138 slsmg_write_nstring(bf, printed);
134 slsmg_write_nstring(dl->line, width - printed - pcnt_width + 1); 139 slsmg_write_nstring(dl->line, width - printed - pcnt_width + 1);
@@ -733,6 +738,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
733 "o Toggle disassembler output/simplified view\n" 738 "o Toggle disassembler output/simplified view\n"
734 "s Toggle source code view\n" 739 "s Toggle source code view\n"
735 "/ Search string\n" 740 "/ Search string\n"
741 "k Toggle line numbers\n"
736 "r Run available scripts\n" 742 "r Run available scripts\n"
737 "? Search string backwards\n"); 743 "? Search string backwards\n");
738 continue; 744 continue;
@@ -741,6 +747,10 @@ static int annotate_browser__run(struct annotate_browser *browser,
741 script_browse(NULL); 747 script_browse(NULL);
742 continue; 748 continue;
743 } 749 }
750 case 'k':
751 annotate_browser__opts.show_linenr =
752 !annotate_browser__opts.show_linenr;
753 break;
744 case 'H': 754 case 'H':
745 nd = browser->curr_hot; 755 nd = browser->curr_hot;
746 break; 756 break;
@@ -984,6 +994,7 @@ static struct annotate_config {
984} annotate__configs[] = { 994} annotate__configs[] = {
985 ANNOTATE_CFG(hide_src_code), 995 ANNOTATE_CFG(hide_src_code),
986 ANNOTATE_CFG(jump_arrows), 996 ANNOTATE_CFG(jump_arrows),
997 ANNOTATE_CFG(show_linenr),
987 ANNOTATE_CFG(show_nr_jumps), 998 ANNOTATE_CFG(show_nr_jumps),
988 ANNOTATE_CFG(use_offset), 999 ANNOTATE_CFG(use_offset),
989}; 1000};
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index cfb976b3de3a..12c17c5a3d68 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -463,23 +463,6 @@ out:
463 return key; 463 return key;
464} 464}
465 465
466static char *callchain_list__sym_name(struct callchain_list *cl,
467 char *bf, size_t bfsize, bool show_dso)
468{
469 int printed;
470
471 if (cl->ms.sym)
472 printed = scnprintf(bf, bfsize, "%s", cl->ms.sym->name);
473 else
474 printed = scnprintf(bf, bfsize, "%#" PRIx64, cl->ip);
475
476 if (show_dso)
477 scnprintf(bf + printed, bfsize - printed, " %s",
478 cl->ms.map ? cl->ms.map->dso->short_name : "unknown");
479
480 return bf;
481}
482
483struct callchain_print_arg { 466struct callchain_print_arg {
484 /* for hists browser */ 467 /* for hists browser */
485 off_t row_offset; 468 off_t row_offset;
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index fc654fb77ace..4b3585eed1e8 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -89,15 +89,6 @@ void perf_gtk__init_hpp(void)
89 perf_gtk__hpp_color_overhead_acc; 89 perf_gtk__hpp_color_overhead_acc;
90} 90}
91 91
92static void callchain_list__sym_name(struct callchain_list *cl,
93 char *bf, size_t bfsize)
94{
95 if (cl->ms.sym)
96 scnprintf(bf, bfsize, "%s", cl->ms.sym->name);
97 else
98 scnprintf(bf, bfsize, "%#" PRIx64, cl->ip);
99}
100
101static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store, 92static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
102 GtkTreeIter *parent, int col, u64 total) 93 GtkTreeIter *parent, int col, u64 total)
103{ 94{
@@ -128,7 +119,7 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
128 scnprintf(buf, sizeof(buf), "%5.2f%%", percent); 119 scnprintf(buf, sizeof(buf), "%5.2f%%", percent);
129 gtk_tree_store_set(store, &iter, 0, buf, -1); 120 gtk_tree_store_set(store, &iter, 0, buf, -1);
130 121
131 callchain_list__sym_name(chain, buf, sizeof(buf)); 122 callchain_list__sym_name(chain, buf, sizeof(buf), false);
132 gtk_tree_store_set(store, &iter, col, buf, -1); 123 gtk_tree_store_set(store, &iter, col, buf, -1);
133 124
134 if (need_new_parent) { 125 if (need_new_parent) {
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 15b451acbde6..dfcbc90146ef 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -41,6 +41,7 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
41{ 41{
42 int i; 42 int i;
43 size_t ret = 0; 43 size_t ret = 0;
44 char bf[1024];
44 45
45 ret += callchain__fprintf_left_margin(fp, left_margin); 46 ret += callchain__fprintf_left_margin(fp, left_margin);
46 for (i = 0; i < depth; i++) { 47 for (i = 0; i < depth; i++) {
@@ -56,11 +57,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
56 } else 57 } else
57 ret += fprintf(fp, "%s", " "); 58 ret += fprintf(fp, "%s", " ");
58 } 59 }
59 if (chain->ms.sym) 60 fputs(callchain_list__sym_name(chain, bf, sizeof(bf), false), fp);
60 ret += fprintf(fp, "%s\n", chain->ms.sym->name); 61 fputc('\n', fp);
61 else
62 ret += fprintf(fp, "0x%0" PRIx64 "\n", chain->ip);
63
64 return ret; 62 return ret;
65} 63}
66 64
@@ -168,6 +166,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
168 struct rb_node *node; 166 struct rb_node *node;
169 int i = 0; 167 int i = 0;
170 int ret = 0; 168 int ret = 0;
169 char bf[1024];
171 170
172 /* 171 /*
173 * If have one single callchain root, don't bother printing 172 * If have one single callchain root, don't bother printing
@@ -196,10 +195,8 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
196 } else 195 } else
197 ret += callchain__fprintf_left_margin(fp, left_margin); 196 ret += callchain__fprintf_left_margin(fp, left_margin);
198 197
199 if (chain->ms.sym) 198 ret += fprintf(fp, "%s\n", callchain_list__sym_name(chain, bf, sizeof(bf),
200 ret += fprintf(fp, " %s\n", chain->ms.sym->name); 199 false));
201 else
202 ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
203 200
204 if (++entries_printed == callchain_param.print_limit) 201 if (++entries_printed == callchain_param.print_limit)
205 break; 202 break;
@@ -219,6 +216,7 @@ static size_t __callchain__fprintf_flat(FILE *fp, struct callchain_node *node,
219{ 216{
220 struct callchain_list *chain; 217 struct callchain_list *chain;
221 size_t ret = 0; 218 size_t ret = 0;
219 char bf[1024];
222 220
223 if (!node) 221 if (!node)
224 return 0; 222 return 0;
@@ -229,11 +227,8 @@ static size_t __callchain__fprintf_flat(FILE *fp, struct callchain_node *node,
229 list_for_each_entry(chain, &node->val, list) { 227 list_for_each_entry(chain, &node->val, list) {
230 if (chain->ip >= PERF_CONTEXT_MAX) 228 if (chain->ip >= PERF_CONTEXT_MAX)
231 continue; 229 continue;
232 if (chain->ms.sym) 230 ret += fprintf(fp, " %s\n", callchain_list__sym_name(chain,
233 ret += fprintf(fp, " %s\n", chain->ms.sym->name); 231 bf, sizeof(bf), false));
234 else
235 ret += fprintf(fp, " %p\n",
236 (void *)(long)chain->ip);
237 } 232 }
238 233
239 return ret; 234 return ret;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 7dabde14ea54..e5670f1af737 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -17,11 +17,13 @@
17#include "debug.h" 17#include "debug.h"
18#include "annotate.h" 18#include "annotate.h"
19#include "evsel.h" 19#include "evsel.h"
20#include <regex.h>
20#include <pthread.h> 21#include <pthread.h>
21#include <linux/bitops.h> 22#include <linux/bitops.h>
22 23
23const char *disassembler_style; 24const char *disassembler_style;
24const char *objdump_path; 25const char *objdump_path;
26static regex_t file_lineno;
25 27
26static struct ins *ins__find(const char *name); 28static struct ins *ins__find(const char *name);
27static int disasm_line__parse(char *line, char **namep, char **rawp); 29static int disasm_line__parse(char *line, char **namep, char **rawp);
@@ -570,13 +572,15 @@ out_free_name:
570 return -1; 572 return -1;
571} 573}
572 574
573static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize) 575static struct disasm_line *disasm_line__new(s64 offset, char *line,
576 size_t privsize, int line_nr)
574{ 577{
575 struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); 578 struct disasm_line *dl = zalloc(sizeof(*dl) + privsize);
576 579
577 if (dl != NULL) { 580 if (dl != NULL) {
578 dl->offset = offset; 581 dl->offset = offset;
579 dl->line = strdup(line); 582 dl->line = strdup(line);
583 dl->line_nr = line_nr;
580 if (dl->line == NULL) 584 if (dl->line == NULL)
581 goto out_delete; 585 goto out_delete;
582 586
@@ -788,13 +792,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
788 * The ops.raw part will be parsed further according to type of the instruction. 792 * The ops.raw part will be parsed further according to type of the instruction.
789 */ 793 */
790static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, 794static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
791 FILE *file, size_t privsize) 795 FILE *file, size_t privsize,
796 int *line_nr)
792{ 797{
793 struct annotation *notes = symbol__annotation(sym); 798 struct annotation *notes = symbol__annotation(sym);
794 struct disasm_line *dl; 799 struct disasm_line *dl;
795 char *line = NULL, *parsed_line, *tmp, *tmp2, *c; 800 char *line = NULL, *parsed_line, *tmp, *tmp2, *c;
796 size_t line_len; 801 size_t line_len;
797 s64 line_ip, offset = -1; 802 s64 line_ip, offset = -1;
803 regmatch_t match[2];
798 804
799 if (getline(&line, &line_len, file) < 0) 805 if (getline(&line, &line_len, file) < 0)
800 return -1; 806 return -1;
@@ -812,6 +818,12 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
812 line_ip = -1; 818 line_ip = -1;
813 parsed_line = line; 819 parsed_line = line;
814 820
821 /* /filename:linenr ? Save line number and ignore. */
822 if (regexec(&file_lineno, line, 2, match, 0) == 0) {
823 *line_nr = atoi(line + match[1].rm_so);
824 return 0;
825 }
826
815 /* 827 /*
816 * Strip leading spaces: 828 * Strip leading spaces:
817 */ 829 */
@@ -842,8 +854,9 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
842 parsed_line = tmp2 + 1; 854 parsed_line = tmp2 + 1;
843 } 855 }
844 856
845 dl = disasm_line__new(offset, parsed_line, privsize); 857 dl = disasm_line__new(offset, parsed_line, privsize, *line_nr);
846 free(line); 858 free(line);
859 (*line_nr)++;
847 860
848 if (dl == NULL) 861 if (dl == NULL)
849 return -1; 862 return -1;
@@ -869,6 +882,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
869 return 0; 882 return 0;
870} 883}
871 884
885static __attribute__((constructor)) void symbol__init_regexpr(void)
886{
887 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED);
888}
889
872static void delete_last_nop(struct symbol *sym) 890static void delete_last_nop(struct symbol *sym)
873{ 891{
874 struct annotation *notes = symbol__annotation(sym); 892 struct annotation *notes = symbol__annotation(sym);
@@ -904,6 +922,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
904 char symfs_filename[PATH_MAX]; 922 char symfs_filename[PATH_MAX];
905 struct kcore_extract kce; 923 struct kcore_extract kce;
906 bool delete_extract = false; 924 bool delete_extract = false;
925 int lineno = 0;
907 926
908 if (filename) 927 if (filename)
909 symbol__join_symfs(symfs_filename, filename); 928 symbol__join_symfs(symfs_filename, filename);
@@ -915,6 +934,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
915 return -ENOMEM; 934 return -ENOMEM;
916 } 935 }
917 goto fallback; 936 goto fallback;
937 } else if (dso__is_kcore(dso)) {
938 goto fallback;
918 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || 939 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
919 strstr(command, "[kernel.kallsyms]") || 940 strstr(command, "[kernel.kallsyms]") ||
920 access(symfs_filename, R_OK)) { 941 access(symfs_filename, R_OK)) {
@@ -982,7 +1003,7 @@ fallback:
982 snprintf(command, sizeof(command), 1003 snprintf(command, sizeof(command),
983 "%s %s%s --start-address=0x%016" PRIx64 1004 "%s %s%s --start-address=0x%016" PRIx64
984 " --stop-address=0x%016" PRIx64 1005 " --stop-address=0x%016" PRIx64
985 " -d %s %s -C %s 2>/dev/null|grep -v %s|expand", 1006 " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand",
986 objdump_path ? objdump_path : "objdump", 1007 objdump_path ? objdump_path : "objdump",
987 disassembler_style ? "-M " : "", 1008 disassembler_style ? "-M " : "",
988 disassembler_style ? disassembler_style : "", 1009 disassembler_style ? disassembler_style : "",
@@ -999,7 +1020,8 @@ fallback:
999 goto out_free_filename; 1020 goto out_free_filename;
1000 1021
1001 while (!feof(file)) 1022 while (!feof(file))
1002 if (symbol__parse_objdump_line(sym, map, file, privsize) < 0) 1023 if (symbol__parse_objdump_line(sym, map, file, privsize,
1024 &lineno) < 0)
1003 break; 1025 break;
1004 1026
1005 /* 1027 /*
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 112d6e268150..0784a9420528 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -58,6 +58,7 @@ struct disasm_line {
58 char *line; 58 char *line;
59 char *name; 59 char *name;
60 struct ins *ins; 60 struct ins *ins;
61 int line_nr;
61 struct ins_operands ops; 62 struct ins_operands ops;
62}; 63};
63 64
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index dd2a3e52ada1..e8d79e5bfaf7 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -18,6 +18,9 @@
18#include "header.h" 18#include "header.h"
19#include "vdso.h" 19#include "vdso.h"
20 20
21
22static bool no_buildid_cache;
23
21int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, 24int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
22 union perf_event *event, 25 union perf_event *event,
23 struct perf_sample *sample, 26 struct perf_sample *sample,
@@ -251,6 +254,11 @@ int dsos__hit_all(struct perf_session *session)
251 return 0; 254 return 0;
252} 255}
253 256
257void disable_buildid_cache(void)
258{
259 no_buildid_cache = true;
260}
261
254int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, 262int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
255 const char *name, bool is_kallsyms, bool is_vdso) 263 const char *name, bool is_kallsyms, bool is_vdso)
256{ 264{
@@ -404,6 +412,9 @@ int perf_session__cache_build_ids(struct perf_session *session)
404 int ret; 412 int ret;
405 char debugdir[PATH_MAX]; 413 char debugdir[PATH_MAX];
406 414
415 if (no_buildid_cache)
416 return 0;
417
407 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); 418 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
408 419
409 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) 420 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 666a3bd4f64e..8236319514d5 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -25,5 +25,6 @@ int perf_session__cache_build_ids(struct perf_session *session);
25int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, 25int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
26 const char *name, bool is_kallsyms, bool is_vdso); 26 const char *name, bool is_kallsyms, bool is_vdso);
27int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir); 27int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir);
28void disable_buildid_cache(void);
28 29
29#endif 30#endif
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 00229809a904..38da69c8c1ff 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -808,3 +808,22 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
808out: 808out:
809 return 1; 809 return 1;
810} 810}
811
812char *callchain_list__sym_name(struct callchain_list *cl,
813 char *bf, size_t bfsize, bool show_dso)
814{
815 int printed;
816
817 if (cl->ms.sym) {
818 printed = scnprintf(bf, bfsize, "%s", cl->ms.sym->name);
819 } else
820 printed = scnprintf(bf, bfsize, "%#" PRIx64, cl->ip);
821
822 if (show_dso)
823 scnprintf(bf + printed, bfsize - printed, " %s",
824 cl->ms.map ?
825 cl->ms.map->dso->short_name :
826 "unknown");
827
828 return bf;
829}
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 3caccc2c173c..3e1ed15d11f1 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -193,4 +193,7 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
193} 193}
194#endif 194#endif
195 195
196char *callchain_list__sym_name(struct callchain_list *cl,
197 char *bf, size_t bfsize, bool show_dso);
198
196#endif /* __PERF_CALLCHAIN_H */ 199#endif /* __PERF_CALLCHAIN_H */
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 7e23dae54f1d..cfbe2b99b9aa 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -816,7 +816,15 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
816 perf_evlist__mmap_get(evlist, idx); 816 perf_evlist__mmap_get(evlist, idx);
817 } 817 }
818 818
819 if (__perf_evlist__add_pollfd(evlist, fd, idx) < 0) { 819 /*
820 * The system_wide flag causes a selected event to be opened
821 * always without a pid. Consequently it will never get a
822 * POLLHUP, but it is used for tracking in combination with
823 * other events, so it should not need to be polled anyway.
824 * Therefore don't add it for polling.
825 */
826 if (!evsel->system_wide &&
827 __perf_evlist__add_pollfd(evlist, fd, idx) < 0) {
820 perf_evlist__mmap_put(evlist, idx); 828 perf_evlist__mmap_put(evlist, idx);
821 return -1; 829 return -1;
822 } 830 }
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 34344ffa79ca..f2dc91fb87fa 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -658,6 +658,14 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
658 attr->mmap_data = track; 658 attr->mmap_data = track;
659 } 659 }
660 660
661 /*
662 * We don't allow user space callchains for function trace
663 * event, due to issues with page faults while tracing page
664 * fault handler and its overall trickiness nature.
665 */
666 if (perf_evsel__is_function_event(evsel))
667 evsel->attr.exclude_callchain_user = 1;
668
661 if (callchain_param.enabled && !evsel->no_aux_samples) 669 if (callchain_param.enabled && !evsel->no_aux_samples)
662 perf_evsel__config_callgraph(evsel); 670 perf_evsel__config_callgraph(evsel);
663 671
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 05fab7a188dc..b20e40c74468 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -24,8 +24,6 @@
24#include "build-id.h" 24#include "build-id.h"
25#include "data.h" 25#include "data.h"
26 26
27static bool no_buildid_cache = false;
28
29static u32 header_argc; 27static u32 header_argc;
30static const char **header_argv; 28static const char **header_argv;
31 29
@@ -191,8 +189,7 @@ static int write_build_id(int fd, struct perf_header *h,
191 pr_debug("failed to write buildid table\n"); 189 pr_debug("failed to write buildid table\n");
192 return err; 190 return err;
193 } 191 }
194 if (!no_buildid_cache) 192 perf_session__cache_build_ids(session);
195 perf_session__cache_build_ids(session);
196 193
197 return 0; 194 return 0;
198} 195}
@@ -2791,8 +2788,3 @@ int perf_event__process_build_id(struct perf_tool *tool __maybe_unused,
2791 session); 2788 session);
2792 return 0; 2789 return 0;
2793} 2790}
2794
2795void disable_buildid_cache(void)
2796{
2797 no_buildid_cache = true;
2798}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 52e94902afb1..d97309c87bd6 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1381,6 +1381,34 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
1381 return mi; 1381 return mi;
1382} 1382}
1383 1383
1384static int add_callchain_ip(struct thread *thread,
1385 struct symbol **parent,
1386 struct addr_location *root_al,
1387 int cpumode,
1388 u64 ip)
1389{
1390 struct addr_location al;
1391
1392 al.filtered = 0;
1393 al.sym = NULL;
1394 thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
1395 ip, &al);
1396 if (al.sym != NULL) {
1397 if (sort__has_parent && !*parent &&
1398 symbol__match_regex(al.sym, &parent_regex))
1399 *parent = al.sym;
1400 else if (have_ignore_callees && root_al &&
1401 symbol__match_regex(al.sym, &ignore_callees_regex)) {
1402 /* Treat this symbol as the root,
1403 forgetting its callees. */
1404 *root_al = al;
1405 callchain_cursor_reset(&callchain_cursor);
1406 }
1407 }
1408
1409 return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym);
1410}
1411
1384struct branch_info *sample__resolve_bstack(struct perf_sample *sample, 1412struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
1385 struct addr_location *al) 1413 struct addr_location *al)
1386{ 1414{
@@ -1427,7 +1455,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1427 1455
1428 for (i = 0; i < chain_nr; i++) { 1456 for (i = 0; i < chain_nr; i++) {
1429 u64 ip; 1457 u64 ip;
1430 struct addr_location al;
1431 1458
1432 if (callchain_param.order == ORDER_CALLEE) 1459 if (callchain_param.order == ORDER_CALLEE)
1433 j = i; 1460 j = i;
@@ -1464,24 +1491,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1464 continue; 1491 continue;
1465 } 1492 }
1466 1493
1467 al.filtered = 0; 1494 err = add_callchain_ip(thread, parent, root_al,
1468 thread__find_addr_location(thread, cpumode, 1495 cpumode, ip);
1469 MAP__FUNCTION, ip, &al); 1496 if (err == -EINVAL)
1470 if (al.sym != NULL) { 1497 break;
1471 if (sort__has_parent && !*parent &&
1472 symbol__match_regex(al.sym, &parent_regex))
1473 *parent = al.sym;
1474 else if (have_ignore_callees && root_al &&
1475 symbol__match_regex(al.sym, &ignore_callees_regex)) {
1476 /* Treat this symbol as the root,
1477 forgetting its callees. */
1478 *root_al = al;
1479 callchain_cursor_reset(&callchain_cursor);
1480 }
1481 }
1482
1483 err = callchain_cursor_append(&callchain_cursor,
1484 ip, al.map, al.sym);
1485 if (err) 1498 if (err)
1486 return err; 1499 return err;
1487 } 1500 }
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9402885a77f3..82a5596241a7 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -309,7 +309,7 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
309static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf, 309static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
310 size_t size, unsigned int width) 310 size_t size, unsigned int width)
311{ 311{
312 return repsep_snprintf(bf, size, "%*.*-s", width, width, he->srcline); 312 return repsep_snprintf(bf, size, "%-*.*s", width, width, he->srcline);
313} 313}
314 314
315struct sort_entry sort_srcline = { 315struct sort_entry sort_srcline = {
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index f3e4bc5fe5d2..77c180637138 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -274,7 +274,7 @@ char *get_srcline(struct dso *dso, unsigned long addr)
274 if (!addr2line(dso_name, addr, &file, &line, dso)) 274 if (!addr2line(dso_name, addr, &file, &line, dso))
275 goto out; 275 goto out;
276 276
277 if (asprintf(&srcline, "%s:%u", file, line) < 0) { 277 if (asprintf(&srcline, "%s:%u", basename(file), line) < 0) {
278 free(file); 278 free(file);
279 goto out; 279 goto out;
280 } 280 }
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index c9541fea9514..fa585c63f56a 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -341,7 +341,6 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
341 341
342 if (filename__read_build_id(ss->name, build_id, BUILD_ID_SIZE) > 0) { 342 if (filename__read_build_id(ss->name, build_id, BUILD_ID_SIZE) > 0) {
343 dso__set_build_id(dso, build_id); 343 dso__set_build_id(dso, build_id);
344 return 1;
345 } 344 }
346 return 0; 345 return 0;
347} 346}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index a2157f0ef1df..9ebc8b1f9be5 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -103,15 +103,14 @@ struct comm *thread__exec_comm(const struct thread *thread)
103 return last; 103 return last;
104} 104}
105 105
106/* CHECKME: time should always be 0 if event aren't ordered */
107int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, 106int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
108 bool exec) 107 bool exec)
109{ 108{
110 struct comm *new, *curr = thread__comm(thread); 109 struct comm *new, *curr = thread__comm(thread);
111 int err; 110 int err;
112 111
113 /* Override latest entry if it had no specific time coverage */ 112 /* Override the default :tid entry */
114 if (!curr->start && !curr->exec) { 113 if (!thread->comm_set) {
115 err = comm__override(curr, str, timestamp, exec); 114 err = comm__override(curr, str, timestamp, exec);
116 if (err) 115 if (err)
117 return err; 116 return err;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 7dc44cfe25b3..76d23d83eae5 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -154,7 +154,6 @@ extern void set_die_routine(void (*routine)(const char *err, va_list params) NOR
154 154
155extern int prefixcmp(const char *str, const char *prefix); 155extern int prefixcmp(const char *str, const char *prefix);
156extern void set_buildid_dir(void); 156extern void set_buildid_dir(void);
157extern void disable_buildid_cache(void);
158 157
159static inline const char *skip_prefix(const char *str, const char *prefix) 158static inline const char *skip_prefix(const char *str, const char *prefix)
160{ 159{