diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-11-27 02:28:44 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-11-27 02:28:44 -0500 |
commit | 3f3b1a46bfdbce97dd3f9594d8a95db82baa554b (patch) | |
tree | 78938a19ac78dbc74c9d507ea3044b29ecb79e1c | |
parent | a95a49fa0cc5eec730d8703b1544fa7ea6a11dec (diff) | |
parent | 43798bf37215fe242e592fd4605d804e2da0781b (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:
- Add 'vmlinux.debug' to the vmlinux search path (Ekaterina Tumanova)
- Do not show sample_(type|period) in the perf_event_attr dump when using
-v with 'perf stat' (Jiri Olsa)
- Display the WEIGHT sample bit, when set, in 'perf evlist -v' (Jiri Olsa)
- Honour --hide-unresolved in 'report', will honour it as well in 'top'
when --hide-unresolved gets supported in that tool (Namhyung Kim)
- Fix freeze wit h--call-graph 'flat/folded' due to not properly
reinitializing the callchain rb_tree (Namhyumg Kim)
- Set dso->long_name when a module name is passed as a parameter
to tools like 'perf probe' but the 'struct dso' associated to that module
still doesn't have the full path for the module, just the '[name]' one
obtained from /proc/modules (Wang Nan)
- Fix anon_hugepage mmaps detection using scanf on /proc/PID/smaps (Yannick Brosseau)
Infrastructure changes:
- Add helper function for updating bpf maps elements (He Kuang)
- Fix traceevents plugins build race (Jiri Olsa)
- Add the $OUTPUT path prefix with 'fixdep' (Jiri Olsa)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | tools/build/Makefile | 2 | ||||
-rw-r--r-- | tools/build/Makefile.include | 2 | ||||
-rw-r--r-- | tools/lib/bpf/bpf.c | 14 | ||||
-rw-r--r-- | tools/lib/bpf/bpf.h | 2 | ||||
-rw-r--r-- | tools/perf/Makefile.perf | 2 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 7 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 67 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 7 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 1 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 1 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 32 | ||||
-rw-r--r-- | tools/perf/util/map.c | 4 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 65 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 3 |
14 files changed, 120 insertions, 89 deletions
diff --git a/tools/build/Makefile b/tools/build/Makefile index a93036272d43..0d5a0e3a8fa9 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile | |||
@@ -25,7 +25,7 @@ export Q srctree CC LD | |||
25 | MAKEFLAGS := --no-print-directory | 25 | MAKEFLAGS := --no-print-directory |
26 | build := -f $(srctree)/tools/build/Makefile.build dir=. obj | 26 | build := -f $(srctree)/tools/build/Makefile.build dir=. obj |
27 | 27 | ||
28 | all: fixdep | 28 | all: $(OUTPUT)fixdep |
29 | 29 | ||
30 | clean: | 30 | clean: |
31 | $(call QUIET_CLEAN, fixdep) | 31 | $(call QUIET_CLEAN, fixdep) |
diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include index 6254760290c9..be630bed66d2 100644 --- a/tools/build/Makefile.include +++ b/tools/build/Makefile.include | |||
@@ -4,7 +4,7 @@ ifdef CROSS_COMPILE | |||
4 | fixdep: | 4 | fixdep: |
5 | else | 5 | else |
6 | fixdep: | 6 | fixdep: |
7 | $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= fixdep | 7 | $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep |
8 | endif | 8 | endif |
9 | 9 | ||
10 | .PHONY: fixdep | 10 | .PHONY: fixdep |
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index a6331050ab79..5bdc6eab6852 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c | |||
@@ -83,3 +83,17 @@ int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns, | |||
83 | log_buf[0] = 0; | 83 | log_buf[0] = 0; |
84 | return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); | 84 | return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); |
85 | } | 85 | } |
86 | |||
87 | int bpf_map_update_elem(int fd, void *key, void *value, | ||
88 | u64 flags) | ||
89 | { | ||
90 | union bpf_attr attr; | ||
91 | |||
92 | bzero(&attr, sizeof(attr)); | ||
93 | attr.map_fd = fd; | ||
94 | attr.key = ptr_to_u64(key); | ||
95 | attr.value = ptr_to_u64(value); | ||
96 | attr.flags = flags; | ||
97 | |||
98 | return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); | ||
99 | } | ||
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 854b7361b784..a76465541292 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h | |||
@@ -20,4 +20,6 @@ int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns, | |||
20 | u32 kern_version, char *log_buf, | 20 | u32 kern_version, char *log_buf, |
21 | size_t log_buf_sz); | 21 | size_t log_buf_sz); |
22 | 22 | ||
23 | int bpf_map_update_elem(int fd, void *key, void *value, | ||
24 | u64 flags); | ||
23 | #endif | 25 | #endif |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 0d19d5447d6c..929a32ba15f5 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -420,7 +420,7 @@ $(LIBTRACEEVENT)-clean: | |||
420 | $(call QUIET_CLEAN, libtraceevent) | 420 | $(call QUIET_CLEAN, libtraceevent) |
421 | $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null | 421 | $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null |
422 | 422 | ||
423 | install-traceevent-plugins: $(LIBTRACEEVENT) | 423 | install-traceevent-plugins: libtraceevent_plugins |
424 | $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins | 424 | $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins |
425 | 425 | ||
426 | $(LIBAPI): fixdep FORCE | 426 | $(LIBAPI): fixdep FORCE |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 14428342b47b..8a9c6908f54e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -45,7 +45,6 @@ struct report { | |||
45 | struct perf_tool tool; | 45 | struct perf_tool tool; |
46 | struct perf_session *session; | 46 | struct perf_session *session; |
47 | bool use_tui, use_gtk, use_stdio; | 47 | bool use_tui, use_gtk, use_stdio; |
48 | bool hide_unresolved; | ||
49 | bool dont_use_callchains; | 48 | bool dont_use_callchains; |
50 | bool show_full_info; | 49 | bool show_full_info; |
51 | bool show_threads; | 50 | bool show_threads; |
@@ -146,7 +145,7 @@ static int process_sample_event(struct perf_tool *tool, | |||
146 | struct hist_entry_iter iter = { | 145 | struct hist_entry_iter iter = { |
147 | .evsel = evsel, | 146 | .evsel = evsel, |
148 | .sample = sample, | 147 | .sample = sample, |
149 | .hide_unresolved = rep->hide_unresolved, | 148 | .hide_unresolved = symbol_conf.hide_unresolved, |
150 | .add_entry_cb = hist_iter__report_callback, | 149 | .add_entry_cb = hist_iter__report_callback, |
151 | }; | 150 | }; |
152 | int ret = 0; | 151 | int ret = 0; |
@@ -157,7 +156,7 @@ static int process_sample_event(struct perf_tool *tool, | |||
157 | return -1; | 156 | return -1; |
158 | } | 157 | } |
159 | 158 | ||
160 | if (rep->hide_unresolved && al.sym == NULL) | 159 | if (symbol_conf.hide_unresolved && al.sym == NULL) |
161 | goto out_put; | 160 | goto out_put; |
162 | 161 | ||
163 | if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) | 162 | if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) |
@@ -740,7 +739,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
740 | OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator", | 739 | OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator", |
741 | "separator for columns, no spaces will be added between " | 740 | "separator for columns, no spaces will be added between " |
742 | "columns '.' is reserved."), | 741 | "columns '.' is reserved."), |
743 | OPT_BOOLEAN('U', "hide-unresolved", &report.hide_unresolved, | 742 | OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved, |
744 | "Only display entries resolved to a symbol"), | 743 | "Only display entries resolved to a symbol"), |
745 | OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", | 744 | OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", |
746 | "Look for files with symbols relative to this directory"), | 745 | "Look for files with symbols relative to this directory"), |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 72b5deb4bd79..3c3f8d0e3064 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -588,8 +588,17 @@ static void print_sample_flags(u32 flags) | |||
588 | printf(" %-4s ", str); | 588 | printf(" %-4s ", str); |
589 | } | 589 | } |
590 | 590 | ||
591 | static void process_event(union perf_event *event, struct perf_sample *sample, | 591 | struct perf_script { |
592 | struct perf_evsel *evsel, struct addr_location *al) | 592 | struct perf_tool tool; |
593 | struct perf_session *session; | ||
594 | bool show_task_events; | ||
595 | bool show_mmap_events; | ||
596 | bool show_switch_events; | ||
597 | }; | ||
598 | |||
599 | static void process_event(struct perf_script *script __maybe_unused, union perf_event *event, | ||
600 | struct perf_sample *sample, struct perf_evsel *evsel, | ||
601 | struct addr_location *al) | ||
593 | { | 602 | { |
594 | struct thread *thread = al->thread; | 603 | struct thread *thread = al->thread; |
595 | struct perf_event_attr *attr = &evsel->attr; | 604 | struct perf_event_attr *attr = &evsel->attr; |
@@ -643,65 +652,33 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
643 | printf("\n"); | 652 | printf("\n"); |
644 | } | 653 | } |
645 | 654 | ||
646 | static int default_start_script(const char *script __maybe_unused, | ||
647 | int argc __maybe_unused, | ||
648 | const char **argv __maybe_unused) | ||
649 | { | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int default_flush_script(void) | ||
654 | { | ||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | static int default_stop_script(void) | ||
659 | { | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static int default_generate_script(struct pevent *pevent __maybe_unused, | ||
664 | const char *outfile __maybe_unused) | ||
665 | { | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | static struct scripting_ops default_scripting_ops = { | ||
670 | .start_script = default_start_script, | ||
671 | .flush_script = default_flush_script, | ||
672 | .stop_script = default_stop_script, | ||
673 | .process_event = process_event, | ||
674 | .generate_script = default_generate_script, | ||
675 | }; | ||
676 | |||
677 | static struct scripting_ops *scripting_ops; | 655 | static struct scripting_ops *scripting_ops; |
678 | 656 | ||
679 | static void setup_scripting(void) | 657 | static void setup_scripting(void) |
680 | { | 658 | { |
681 | setup_perl_scripting(); | 659 | setup_perl_scripting(); |
682 | setup_python_scripting(); | 660 | setup_python_scripting(); |
683 | |||
684 | scripting_ops = &default_scripting_ops; | ||
685 | } | 661 | } |
686 | 662 | ||
687 | static int flush_scripting(void) | 663 | static int flush_scripting(void) |
688 | { | 664 | { |
689 | return scripting_ops->flush_script(); | 665 | return scripting_ops ? scripting_ops->flush_script() : 0; |
690 | } | 666 | } |
691 | 667 | ||
692 | static int cleanup_scripting(void) | 668 | static int cleanup_scripting(void) |
693 | { | 669 | { |
694 | pr_debug("\nperf script stopped\n"); | 670 | pr_debug("\nperf script stopped\n"); |
695 | 671 | ||
696 | return scripting_ops->stop_script(); | 672 | return scripting_ops ? scripting_ops->stop_script() : 0; |
697 | } | 673 | } |
698 | 674 | ||
699 | static int process_sample_event(struct perf_tool *tool __maybe_unused, | 675 | static int process_sample_event(struct perf_tool *tool, |
700 | union perf_event *event, | 676 | union perf_event *event, |
701 | struct perf_sample *sample, | 677 | struct perf_sample *sample, |
702 | struct perf_evsel *evsel, | 678 | struct perf_evsel *evsel, |
703 | struct machine *machine) | 679 | struct machine *machine) |
704 | { | 680 | { |
681 | struct perf_script *scr = container_of(tool, struct perf_script, tool); | ||
705 | struct addr_location al; | 682 | struct addr_location al; |
706 | 683 | ||
707 | if (debug_mode) { | 684 | if (debug_mode) { |
@@ -727,20 +704,16 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
727 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) | 704 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) |
728 | goto out_put; | 705 | goto out_put; |
729 | 706 | ||
730 | scripting_ops->process_event(event, sample, evsel, &al); | 707 | if (scripting_ops) |
708 | scripting_ops->process_event(event, sample, evsel, &al); | ||
709 | else | ||
710 | process_event(scr, event, sample, evsel, &al); | ||
711 | |||
731 | out_put: | 712 | out_put: |
732 | addr_location__put(&al); | 713 | addr_location__put(&al); |
733 | return 0; | 714 | return 0; |
734 | } | 715 | } |
735 | 716 | ||
736 | struct perf_script { | ||
737 | struct perf_tool tool; | ||
738 | struct perf_session *session; | ||
739 | bool show_task_events; | ||
740 | bool show_mmap_events; | ||
741 | bool show_switch_events; | ||
742 | }; | ||
743 | |||
744 | static int process_attr(struct perf_tool *tool, union perf_event *event, | 717 | static int process_attr(struct perf_tool *tool, union perf_event *event, |
745 | struct perf_evlist **pevlist) | 718 | struct perf_evlist **pevlist) |
746 | { | 719 | { |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e77880b5094d..df2fbf046ee2 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -161,6 +161,13 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
161 | 161 | ||
162 | attr->inherit = !no_inherit; | 162 | attr->inherit = !no_inherit; |
163 | 163 | ||
164 | /* | ||
165 | * Some events get initialized with sample_(period/type) set, | ||
166 | * like tracepoints. Clear it up for counting. | ||
167 | */ | ||
168 | attr->sample_period = 0; | ||
169 | attr->sample_type = 0; | ||
170 | |||
164 | if (target__has_cpu(&target)) | 171 | if (target__has_cpu(&target)) |
165 | return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); | 172 | return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); |
166 | 173 | ||
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index fc3b1e0d09ee..564377d2bebf 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -290,6 +290,7 @@ static void | |||
290 | sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root, | 290 | sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root, |
291 | u64 min_hit, struct callchain_param *param __maybe_unused) | 291 | u64 min_hit, struct callchain_param *param __maybe_unused) |
292 | { | 292 | { |
293 | *rb_root = RB_ROOT; | ||
293 | __sort_chain_flat(rb_root, &root->node, min_hit); | 294 | __sort_chain_flat(rb_root, &root->node, min_hit); |
294 | } | 295 | } |
295 | 296 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 397fb4ed3c97..0a1f4d9e52fc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -1192,6 +1192,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value) | |||
1192 | bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), | 1192 | bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), |
1193 | bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), | 1193 | bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), |
1194 | bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), | 1194 | bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), |
1195 | bit_name(WEIGHT), | ||
1195 | { .name = NULL, } | 1196 | { .name = NULL, } |
1196 | }; | 1197 | }; |
1197 | #undef bit_name | 1198 | #undef bit_name |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7f5071a4d9aa..95a7f6087346 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -561,6 +561,24 @@ int machine__process_switch_event(struct machine *machine __maybe_unused, | |||
561 | return 0; | 561 | return 0; |
562 | } | 562 | } |
563 | 563 | ||
564 | static void dso__adjust_kmod_long_name(struct dso *dso, const char *filename) | ||
565 | { | ||
566 | const char *dup_filename; | ||
567 | |||
568 | if (!filename || !dso || !dso->long_name) | ||
569 | return; | ||
570 | if (dso->long_name[0] != '[') | ||
571 | return; | ||
572 | if (!strchr(filename, '/')) | ||
573 | return; | ||
574 | |||
575 | dup_filename = strdup(filename); | ||
576 | if (!dup_filename) | ||
577 | return; | ||
578 | |||
579 | dso__set_long_name(dso, filename, true); | ||
580 | } | ||
581 | |||
564 | struct map *machine__findnew_module_map(struct machine *machine, u64 start, | 582 | struct map *machine__findnew_module_map(struct machine *machine, u64 start, |
565 | const char *filename) | 583 | const char *filename) |
566 | { | 584 | { |
@@ -573,8 +591,15 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start, | |||
573 | 591 | ||
574 | map = map_groups__find_by_name(&machine->kmaps, MAP__FUNCTION, | 592 | map = map_groups__find_by_name(&machine->kmaps, MAP__FUNCTION, |
575 | m.name); | 593 | m.name); |
576 | if (map) | 594 | if (map) { |
595 | /* | ||
596 | * If the map's dso is an offline module, give dso__load() | ||
597 | * a chance to find the file path of that module by fixing | ||
598 | * long_name. | ||
599 | */ | ||
600 | dso__adjust_kmod_long_name(map->dso, filename); | ||
577 | goto out; | 601 | goto out; |
602 | } | ||
578 | 603 | ||
579 | dso = machine__findnew_module_dso(machine, &m, filename); | 604 | dso = machine__findnew_module_dso(machine, &m, filename); |
580 | if (dso == NULL) | 605 | if (dso == NULL) |
@@ -1618,6 +1643,8 @@ static int add_callchain_ip(struct thread *thread, | |||
1618 | } | 1643 | } |
1619 | } | 1644 | } |
1620 | 1645 | ||
1646 | if (symbol_conf.hide_unresolved && al.sym == NULL) | ||
1647 | return 0; | ||
1621 | return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym); | 1648 | return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym); |
1622 | } | 1649 | } |
1623 | 1650 | ||
@@ -1872,6 +1899,9 @@ check_calls: | |||
1872 | static int unwind_entry(struct unwind_entry *entry, void *arg) | 1899 | static int unwind_entry(struct unwind_entry *entry, void *arg) |
1873 | { | 1900 | { |
1874 | struct callchain_cursor *cursor = arg; | 1901 | struct callchain_cursor *cursor = arg; |
1902 | |||
1903 | if (symbol_conf.hide_unresolved && entry->sym == NULL) | ||
1904 | return 0; | ||
1875 | return callchain_cursor_append(cursor, entry->ip, | 1905 | return callchain_cursor_append(cursor, entry->ip, |
1876 | entry->map, entry->sym); | 1906 | entry->map, entry->sym); |
1877 | } | 1907 | } |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index afc6b56cf749..93d9f1ce3baa 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -26,8 +26,8 @@ const char *map_type__name[MAP__NR_TYPES] = { | |||
26 | static inline int is_anon_memory(const char *filename) | 26 | static inline int is_anon_memory(const char *filename) |
27 | { | 27 | { |
28 | return !strcmp(filename, "//anon") || | 28 | return !strcmp(filename, "//anon") || |
29 | !strcmp(filename, "/dev/zero (deleted)") || | 29 | !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) || |
30 | !strcmp(filename, "/anon_hugepage (deleted)"); | 30 | !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1); |
31 | } | 31 | } |
32 | 32 | ||
33 | static inline int is_no_dso_memory(const char *filename) | 33 | static inline int is_no_dso_memory(const char *filename) |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index cd08027a6d2c..d51abd2e7865 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1860,24 +1860,44 @@ static void vmlinux_path__exit(void) | |||
1860 | zfree(&vmlinux_path); | 1860 | zfree(&vmlinux_path); |
1861 | } | 1861 | } |
1862 | 1862 | ||
1863 | static const char * const vmlinux_paths[] = { | ||
1864 | "vmlinux", | ||
1865 | "/boot/vmlinux" | ||
1866 | }; | ||
1867 | |||
1868 | static const char * const vmlinux_paths_upd[] = { | ||
1869 | "/boot/vmlinux-%s", | ||
1870 | "/usr/lib/debug/boot/vmlinux-%s", | ||
1871 | "/lib/modules/%s/build/vmlinux", | ||
1872 | "/usr/lib/debug/lib/modules/%s/vmlinux", | ||
1873 | "/usr/lib/debug/boot/vmlinux-%s.debug" | ||
1874 | }; | ||
1875 | |||
1876 | static int vmlinux_path__add(const char *new_entry) | ||
1877 | { | ||
1878 | vmlinux_path[vmlinux_path__nr_entries] = strdup(new_entry); | ||
1879 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | ||
1880 | return -1; | ||
1881 | ++vmlinux_path__nr_entries; | ||
1882 | |||
1883 | return 0; | ||
1884 | } | ||
1885 | |||
1863 | static int vmlinux_path__init(struct perf_env *env) | 1886 | static int vmlinux_path__init(struct perf_env *env) |
1864 | { | 1887 | { |
1865 | struct utsname uts; | 1888 | struct utsname uts; |
1866 | char bf[PATH_MAX]; | 1889 | char bf[PATH_MAX]; |
1867 | char *kernel_version; | 1890 | char *kernel_version; |
1891 | unsigned int i; | ||
1868 | 1892 | ||
1869 | vmlinux_path = malloc(sizeof(char *) * 6); | 1893 | vmlinux_path = malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) + |
1894 | ARRAY_SIZE(vmlinux_paths_upd))); | ||
1870 | if (vmlinux_path == NULL) | 1895 | if (vmlinux_path == NULL) |
1871 | return -1; | 1896 | return -1; |
1872 | 1897 | ||
1873 | vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux"); | 1898 | for (i = 0; i < ARRAY_SIZE(vmlinux_paths); i++) |
1874 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | 1899 | if (vmlinux_path__add(vmlinux_paths[i]) < 0) |
1875 | goto out_fail; | 1900 | goto out_fail; |
1876 | ++vmlinux_path__nr_entries; | ||
1877 | vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux"); | ||
1878 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | ||
1879 | goto out_fail; | ||
1880 | ++vmlinux_path__nr_entries; | ||
1881 | 1901 | ||
1882 | /* only try kernel version if no symfs was given */ | 1902 | /* only try kernel version if no symfs was given */ |
1883 | if (symbol_conf.symfs[0] != 0) | 1903 | if (symbol_conf.symfs[0] != 0) |
@@ -1892,28 +1912,11 @@ static int vmlinux_path__init(struct perf_env *env) | |||
1892 | kernel_version = uts.release; | 1912 | kernel_version = uts.release; |
1893 | } | 1913 | } |
1894 | 1914 | ||
1895 | snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version); | 1915 | for (i = 0; i < ARRAY_SIZE(vmlinux_paths_upd); i++) { |
1896 | vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); | 1916 | snprintf(bf, sizeof(bf), vmlinux_paths_upd[i], kernel_version); |
1897 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | 1917 | if (vmlinux_path__add(bf) < 0) |
1898 | goto out_fail; | 1918 | goto out_fail; |
1899 | ++vmlinux_path__nr_entries; | 1919 | } |
1900 | snprintf(bf, sizeof(bf), "/usr/lib/debug/boot/vmlinux-%s", | ||
1901 | kernel_version); | ||
1902 | vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); | ||
1903 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | ||
1904 | goto out_fail; | ||
1905 | ++vmlinux_path__nr_entries; | ||
1906 | snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version); | ||
1907 | vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); | ||
1908 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | ||
1909 | goto out_fail; | ||
1910 | ++vmlinux_path__nr_entries; | ||
1911 | snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", | ||
1912 | kernel_version); | ||
1913 | vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); | ||
1914 | if (vmlinux_path[vmlinux_path__nr_entries] == NULL) | ||
1915 | goto out_fail; | ||
1916 | ++vmlinux_path__nr_entries; | ||
1917 | 1920 | ||
1918 | return 0; | 1921 | return 0; |
1919 | 1922 | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index dcd786e364f2..857f707ac12b 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -108,7 +108,8 @@ struct symbol_conf { | |||
108 | show_hist_headers, | 108 | show_hist_headers, |
109 | branch_callstack, | 109 | branch_callstack, |
110 | has_filter, | 110 | has_filter, |
111 | show_ref_callgraph; | 111 | show_ref_callgraph, |
112 | hide_unresolved; | ||
112 | const char *vmlinux_name, | 113 | const char *vmlinux_name, |
113 | *kallsyms_name, | 114 | *kallsyms_name, |
114 | *source_prefix, | 115 | *source_prefix, |