From b49a8fe52626814968b9a9d27d7ad1cadc5532ed Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 26 Nov 2015 16:08:20 +0900 Subject: [PATCH 01/13] perf callchain: Honor hide_unresolved If user requested to hide unresolved entries, skip unresolved callchains as well as hist entries. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Kan Liang Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1448521700-32062-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 7 +++---- tools/perf/util/machine.c | 5 +++++ tools/perf/util/symbol.h | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) 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 { struct perf_tool tool; struct perf_session *session; bool use_tui, use_gtk, use_stdio; - bool hide_unresolved; bool dont_use_callchains; bool show_full_info; bool show_threads; @@ -146,7 +145,7 @@ static int process_sample_event(struct perf_tool *tool, struct hist_entry_iter iter = { .evsel = evsel, .sample = sample, - .hide_unresolved = rep->hide_unresolved, + .hide_unresolved = symbol_conf.hide_unresolved, .add_entry_cb = hist_iter__report_callback, }; int ret = 0; @@ -157,7 +156,7 @@ static int process_sample_event(struct perf_tool *tool, return -1; } - if (rep->hide_unresolved && al.sym == NULL) + if (symbol_conf.hide_unresolved && al.sym == NULL) goto out_put; 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) OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator", "separator for columns, no spaces will be added between " "columns '.' is reserved."), - OPT_BOOLEAN('U', "hide-unresolved", &report.hide_unresolved, + OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved, "Only display entries resolved to a symbol"), OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", "Look for files with symbols relative to this directory"), diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7f5071a4d9aa..f0019b72db48 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1618,6 +1618,8 @@ static int add_callchain_ip(struct thread *thread, } } + if (symbol_conf.hide_unresolved && al.sym == NULL) + return 0; return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym); } @@ -1872,6 +1874,9 @@ check_calls: static int unwind_entry(struct unwind_entry *entry, void *arg) { struct callchain_cursor *cursor = arg; + + if (symbol_conf.hide_unresolved && entry->sym == NULL) + return 0; return callchain_cursor_append(cursor, entry->ip, entry->map, entry->sym); } 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 { show_hist_headers, branch_callstack, has_filter, - show_ref_callgraph; + show_ref_callgraph, + hide_unresolved; const char *vmlinux_name, *kallsyms_name, *source_prefix, From 0356218a68551f051998f4fb5074a1eed7a346fe Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 26 Nov 2015 16:08:18 +0900 Subject: [PATCH 02/13] perf top: Fix freeze on --call-graph flat/folded The callchain rbtree is rebuilt periodically, so it needs to reinitialize the root everytime. Otherwise it can be stuck in the rbtree insertion with stale pointers. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1448521700-32062-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/callchain.c | 1 + 1 file changed, 1 insertion(+) 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 sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root, u64 min_hit, struct callchain_param *param __maybe_unused) { + *rb_root = RB_ROOT; __sort_chain_flat(rb_root, &root->node, min_hit); } From 2aaecfc51bc65532152e141df3268fda06cae029 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 26 Nov 2015 14:55:23 +0100 Subject: [PATCH 03/13] perf script: Remove default_scripting_ops The default script handler (the one that displays samples on screen) is implemented scripting_ops instance with process_event callback. This way we can't pass any script config into display function, because we don't want perl or python handlers to be depended on perf script internals. Removing the default_scripting_ops and calling process event function directly. This way it's possible to pass perf_script struct and process configuration data in following commit. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1448546125-29245-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 43 ++++++------------------------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 72b5deb4bd79..8e3f8048d2d0 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -643,57 +643,24 @@ static void process_event(union perf_event *event, struct perf_sample *sample, printf("\n"); } -static int default_start_script(const char *script __maybe_unused, - int argc __maybe_unused, - const char **argv __maybe_unused) -{ - return 0; -} - -static int default_flush_script(void) -{ - return 0; -} - -static int default_stop_script(void) -{ - return 0; -} - -static int default_generate_script(struct pevent *pevent __maybe_unused, - const char *outfile __maybe_unused) -{ - return 0; -} - -static struct scripting_ops default_scripting_ops = { - .start_script = default_start_script, - .flush_script = default_flush_script, - .stop_script = default_stop_script, - .process_event = process_event, - .generate_script = default_generate_script, -}; - static struct scripting_ops *scripting_ops; static void setup_scripting(void) { setup_perl_scripting(); setup_python_scripting(); - - scripting_ops = &default_scripting_ops; } static int flush_scripting(void) { - return scripting_ops->flush_script(); + return scripting_ops ? scripting_ops->flush_script() : 0; } static int cleanup_scripting(void) { pr_debug("\nperf script stopped\n"); - return scripting_ops->stop_script(); + return scripting_ops ? scripting_ops->stop_script() : 0; } static int process_sample_event(struct perf_tool *tool __maybe_unused, @@ -727,7 +694,11 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) goto out_put; - scripting_ops->process_event(event, sample, evsel, &al); + if (scripting_ops) + scripting_ops->process_event(event, sample, evsel, &al); + else + process_event(event, sample, evsel, &al); + out_put: addr_location__put(&al); return 0; From 67befc652845c8ffbefc8d173a6e6ced14d472f1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 26 Nov 2015 14:54:04 +0100 Subject: [PATCH 04/13] perf build: Fix traceevent plugins build race Ingo reported following build failure: $ make clean install ... CC plugin_kmem.o fixdep: error opening depfile: ./.plugin_hrtimer.o.d: No such file or directory /home/mingo/tip/tools/build/Makefile.build:77: recipe for target 'plugin_hrtimer.o' failed make[3]: *** [plugin_hrtimer.o] Error 2 Makefile:189: recipe for target 'plugin_hrtimer-in.o' failed make[2]: *** [plugin_hrtimer-in.o] Error 2 Makefile.perf:414: recipe for target 'libtraceevent_plugins' failed make[1]: *** [libtraceevent_plugins] Error 2 make[1]: *** Waiting for unfinished jobs.... Currently we have the install-traceevent-plugins target being dependent on $(LIBTRACEEVENT), which will actualy not build any plugin. So the install-traceevent-plugins target itself will try to build plugins, but.. Plugins built is also triggered by perf build itself via libtraceevent_plugins target. This might cause a race having one make thread removing temp files from another and result in above error. Fixing this by having proper plugins build dependency before installing plugins. Reported-and-Tested-by:: Ingo Molnar Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1448546044-28973-3-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: $(call QUIET_CLEAN, libtraceevent) $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null -install-traceevent-plugins: $(LIBTRACEEVENT) +install-traceevent-plugins: libtraceevent_plugins $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins $(LIBAPI): fixdep FORCE From c03d5184f0e92fa696e4b57f54ffc3b19a92f704 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Thu, 26 Nov 2015 03:59:57 +0000 Subject: [PATCH 05/13] perf machine: Adjust dso->long_name for offline module Something unexpected may happen if copy statically linked perf to a production environment: # ./perf probe -m ./mymodule.ko my_func [mymodule] with build id 326ab42550ef3d24944f53c817533728367effeb not found, continuing without symbols Failed to find symbol my_func in /home/wangnan/kmodule/mymodule.ko Error: Failed to add events. # ./perf buildid-cache -a ./mymodule.ko # ./perf probe -m ./mymodule.ko my_func Added new event: probe:my_func (on my_func in /home/wangnan/kmodule/mymodule.ko) You can now use it in all perf tools, such as: perf record -e probe:my_func -aR sleep 1 Where: # ldd ./perf not a dynamic executable # strace -e open ./perf probe -m ./mymodule.ko my_func ... open("/home/wangnan/kmodule/mymodule.ko", O_RDONLY) = 3 open("/home/wangnan/kmodule/../lib64/elfutils/libebl_x86_64.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) ... open("/lib64/tls/libebl_x86_64.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libebl_x86_64.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib64/tls/libebl_x86_64.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib64/libebl_x86_64.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("[mymodule]", O_RDONLY) = -1 ENOENT (No such file or directory) open("/home/wangnan/.debug/.build-id/32/6ab42550ef3d24944f53c817533728367effeb", O_RDONLY) = -1 ENOENT (No such file or directory) open("[mymodule]", O_RDONLY) = -1 ENOENT (No such file or directory) In the above example, probe fails before we put the module into buildid-cache. However, user would expect it success in both case because perf is able to find probe points actually. The reason is because perf won't utilize module's full path if it failed to open debuginfo. In: convert_to_probe_trace_events -> find_probe_trace_events_from_map -> get_target_map -> kernel_get_module_map -> machine__findnew_module_map -> map_groups__find_by_name map_groups__find_by_name() is able to find the map of that module, but this information is found from /proc/module before it knows the real path of the offline module. Therefore, the map->dso->long_name is set to something like '[mymodule]', which prevent dso__load() find the real path of the module file. In another aspect, if dso__load() can get the offline module through buildid cache, it can read symble table from that ko. Even if debuginfo is not available, 'perf probe' can success if the '.symtab' can be found. This patch improves machine__findnew_module_map(): when dso->long_name is leading with '[' (doesn't find path of module when parsing /proc/modules), fixes it by dso__set_long_name(), so following dso__load() is possible to find the symbol table. This patch won't interfere with buildid matching. Here is the test result: # ./perf probe -m ./mymodule.ko my_func Added new event: probe:my_func (on my_func in /home/wangnan/kmodule/mymodule.ko) You can now use it in all perf tools, such as: perf record -e probe:my_func -aR sleep 1 # ./perf probe -d '*' Removed event: probe:my_func # mv ./mymodule.{ko,.bak} # mv ./moduleb.ko mymodule.ko # ./perf probe -m ./mymodule.ko my_func /home/wangnan/kmodule/mymodule.ko with build id 326ab42550ef3d24944f53c817533728367effeb not found, continuing without symbols Failed to find symbol my_func in /home/wangnan/kmodule/mymodule.ko Error: Failed to add events. # ./perf probe -v -m ./mymodule.ko my_func probe-definition(0): my_func symbol:my_func file:(null) line:0 offset:0 return:0 lazy:(null) 0 arguments Could not open debuginfo. Try to use symbols. symsrc__init: build id mismatch for /home/wangnan/kmodule/mymodule.ko. /home/wangnan/kmodule/mymodule.ko with build id 326ab42550ef3d24944f53c817533728367effeb not found, continuing without symbols Failed to find symbol my_func in /home/wangnan/kmodule/mymodule.ko Error: Failed to add events. Reason: No such file or directory (Code: -2) Signed-off-by: Wang Nan Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1448510397-187965-1-git-send-email-wangnan0@huawei.com [ Renamed adjust_dso_long_name() do dso__adjust_kmod_long_name() ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index f0019b72db48..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, return 0; } +static void dso__adjust_kmod_long_name(struct dso *dso, const char *filename) +{ + const char *dup_filename; + + if (!filename || !dso || !dso->long_name) + return; + if (dso->long_name[0] != '[') + return; + if (!strchr(filename, '/')) + return; + + dup_filename = strdup(filename); + if (!dup_filename) + return; + + dso__set_long_name(dso, filename, true); +} + struct map *machine__findnew_module_map(struct machine *machine, u64 start, const char *filename) { @@ -573,8 +591,15 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start, map = map_groups__find_by_name(&machine->kmaps, MAP__FUNCTION, m.name); - if (map) + if (map) { + /* + * If the map's dso is an offline module, give dso__load() + * a chance to find the file path of that module by fixing + * long_name. + */ + dso__adjust_kmod_long_name(map->dso, filename); goto out; + } dso = machine__findnew_module_dso(machine, &m, filename); if (dso == NULL) From b2be5451f660e0ee230969cc24121d9e210a91de Mon Sep 17 00:00:00 2001 From: Yannick Brosseau Date: Thu, 26 Nov 2015 03:42:32 -0800 Subject: [PATCH 06/13] perf tools: Correctly identify anon_hugepage when generating map (v2) When parsing /proc/xxx/maps, the sscanf in perf_event__synthesize_mmap_events truncate the map name at the space in "/anon_hugepage (deleted)". is_anon_memory() then only receives the string "/anon_hugepage" and does not detect it. We change is_anon_memory() to only compare the first part of the string, effectively ignoring if " (deleted)" is there. Signed-off-by: Yannick Brosseau Tested-by: Arnaldo Carvalho de Melo Cc: Andi Kleen Cc: Joshua Zhu Cc: kernel-team@fb.com Link: http://lkml.kernel.org/r/1448538152-2898-1-git-send-email-scientist@fb.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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] = { static inline int is_anon_memory(const char *filename) { return !strcmp(filename, "//anon") || - !strcmp(filename, "/dev/zero (deleted)") || - !strcmp(filename, "/anon_hugepage (deleted)"); + !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) || + !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1); } static inline int is_no_dso_memory(const char *filename) From 809e9423d7bc72e50d94d8267bab010a007a6137 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 26 Nov 2015 18:55:21 +0100 Subject: [PATCH 07/13] perf script: Pass perf_script into process_event Passing perf_script struct into process_event function, so we could process configuration data for event printing. It will be used in following patch to get event name string width. Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20151126175521.GA18979@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8e3f8048d2d0..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) printf(" %-4s ", str); } -static void process_event(union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel, struct addr_location *al) +struct perf_script { + struct perf_tool tool; + struct perf_session *session; + bool show_task_events; + bool show_mmap_events; + bool show_switch_events; +}; + +static void process_event(struct perf_script *script __maybe_unused, union perf_event *event, + struct perf_sample *sample, struct perf_evsel *evsel, + struct addr_location *al) { struct thread *thread = al->thread; struct perf_event_attr *attr = &evsel->attr; @@ -663,12 +672,13 @@ static int cleanup_scripting(void) return scripting_ops ? scripting_ops->stop_script() : 0; } -static int process_sample_event(struct perf_tool *tool __maybe_unused, +static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine) { + struct perf_script *scr = container_of(tool, struct perf_script, tool); struct addr_location al; if (debug_mode) { @@ -697,21 +707,13 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, if (scripting_ops) scripting_ops->process_event(event, sample, evsel, &al); else - process_event(event, sample, evsel, &al); + process_event(scr, event, sample, evsel, &al); out_put: addr_location__put(&al); return 0; } -struct perf_script { - struct perf_tool tool; - struct perf_session *session; - bool show_task_events; - bool show_mmap_events; - bool show_switch_events; -}; - static int process_attr(struct perf_tool *tool, union perf_event *event, struct perf_evlist **pevlist) { From 5e50426d5d9049dfdb8b2b18e761717e7e80a6ad Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 26 Nov 2015 19:50:55 +0100 Subject: [PATCH 08/13] tools build: Use fixdep with OUTPUT path prefix Adding OUTPUT path prefix for fixdep target so we use it properly in out of tree builds. If the fixdep already existed in the tree, the out of tree build would see it already exist and did not build the out of tree version, as reported by Arnaldo: [acme@zoo linux]$ make O=/tmp/build/perf -C tools/perf make: Entering directory '/home/git/linux/tools/perf' BUILD: Doing 'make -j4' parallel build make[2]: Nothing to be done for 'fixdep'. make: Leaving directory '/home/git/linux/tools/perf' Reported-and-Tested-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/20151126185055.GC19410@krava.brq.redhat.com [ Fixed conflict with 5725dd8fa888 ("tools build: Clean CFLAGS and LDFLAGS for fixdep") ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile | 2 +- tools/build/Makefile.include | 2 +- 2 files changed, 2 insertions(+), 2 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 MAKEFLAGS := --no-print-directory build := -f $(srctree)/tools/build/Makefile.build dir=. obj -all: fixdep +all: $(OUTPUT)fixdep clean: $(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 fixdep: else fixdep: - $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= fixdep + $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep endif .PHONY: fixdep From aac4864727f4b3838ec1c03277bbc47a237b7516 Mon Sep 17 00:00:00 2001 From: Ekaterina Tumanova Date: Wed, 25 Nov 2015 17:32:45 +0100 Subject: [PATCH 09/13] perf symbols: Refactor vmlinux_path__init() to ease path additions Refactor vmlinux_path__init() to ease subsequent additions of new vmlinux locations. Signed-off-by: Ekaterina Tumanova Acked-by: Alexander Yarygin Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Christian Borntraeger Cc: David Ahern Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1448469166-61363-2-git-send-email-tumanova@linux.vnet.ibm.com [ Rename vmlinux_path__update() to vmlinux_path__add() ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 64 +++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index cd08027a6d2c..e2ac6b6676e4 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1860,24 +1860,43 @@ static void vmlinux_path__exit(void) zfree(&vmlinux_path); } +static const char * const vmlinux_paths[] = { + "vmlinux", + "/boot/vmlinux" +}; + +static const char * const vmlinux_paths_upd[] = { + "/boot/vmlinux-%s", + "/usr/lib/debug/boot/vmlinux-%s", + "/lib/modules/%s/build/vmlinux", + "/usr/lib/debug/lib/modules/%s/vmlinux" +}; + +static int vmlinux_path__add(const char *new_entry) +{ + vmlinux_path[vmlinux_path__nr_entries] = strdup(new_entry); + if (vmlinux_path[vmlinux_path__nr_entries] == NULL) + return -1; + ++vmlinux_path__nr_entries; + + return 0; +} + static int vmlinux_path__init(struct perf_env *env) { struct utsname uts; char bf[PATH_MAX]; char *kernel_version; + unsigned int i; - vmlinux_path = malloc(sizeof(char *) * 6); + vmlinux_path = malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) + + ARRAY_SIZE(vmlinux_paths_upd))); if (vmlinux_path == NULL) return -1; - vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux"); - if (vmlinux_path[vmlinux_path__nr_entries] == NULL) - goto out_fail; - ++vmlinux_path__nr_entries; - vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux"); - if (vmlinux_path[vmlinux_path__nr_entries] == NULL) - goto out_fail; - ++vmlinux_path__nr_entries; + for (i = 0; i < ARRAY_SIZE(vmlinux_paths); i++) + if (vmlinux_path__add(vmlinux_paths[i]) < 0) + goto out_fail; /* only try kernel version if no symfs was given */ if (symbol_conf.symfs[0] != 0) @@ -1892,28 +1911,11 @@ static int vmlinux_path__init(struct perf_env *env) kernel_version = uts.release; } - snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version); - vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); - if (vmlinux_path[vmlinux_path__nr_entries] == NULL) - goto out_fail; - ++vmlinux_path__nr_entries; - snprintf(bf, sizeof(bf), "/usr/lib/debug/boot/vmlinux-%s", - kernel_version); - vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); - if (vmlinux_path[vmlinux_path__nr_entries] == NULL) - goto out_fail; - ++vmlinux_path__nr_entries; - snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version); - vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); - if (vmlinux_path[vmlinux_path__nr_entries] == NULL) - goto out_fail; - ++vmlinux_path__nr_entries; - snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", - kernel_version); - vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); - if (vmlinux_path[vmlinux_path__nr_entries] == NULL) - goto out_fail; - ++vmlinux_path__nr_entries; + for (i = 0; i < ARRAY_SIZE(vmlinux_paths_upd); i++) { + snprintf(bf, sizeof(bf), vmlinux_paths_upd[i], kernel_version); + if (vmlinux_path__add(bf) < 0) + goto out_fail; + } return 0; From f55ae9540d16a355e61cb57b035aab9e1ae2da28 Mon Sep 17 00:00:00 2001 From: Ekaterina Tumanova Date: Wed, 25 Nov 2015 17:32:46 +0100 Subject: [PATCH 10/13] perf symbols: Add the path to vmlinux.debug Currently when debuginfo is separated to vmlinux.debug, it's contents get ignored. Let's change that and add it to the vmlinux_path list. Signed-off-by: Ekaterina Tumanova Acked-by: Alexander Yarygin Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Christian Borntraeger Cc: David Ahern Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/1448469166-61363-3-git-send-email-tumanova@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e2ac6b6676e4..d51abd2e7865 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1869,7 +1869,8 @@ static const char * const vmlinux_paths_upd[] = { "/boot/vmlinux-%s", "/usr/lib/debug/boot/vmlinux-%s", "/lib/modules/%s/build/vmlinux", - "/usr/lib/debug/lib/modules/%s/vmlinux" + "/usr/lib/debug/lib/modules/%s/vmlinux", + "/usr/lib/debug/boot/vmlinux-%s.debug" }; static int vmlinux_path__add(const char *new_entry) From 6acd8e9271cdeaec458fd4eec4a6765d16e0e61c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 25 Nov 2015 16:36:54 +0100 Subject: [PATCH 11/13] perf stat: Clear sample_(type|period) for counting Clear sample_(type|period) for counting, as it only confuses debug output with unwanted sampling details: Before: $ sudo perf stat -e 'raw_syscalls:sys_enter' -vv ls ------------------------------------------------------------ perf_event_attr: type 2 size 112 config 0x11 { sample_period, sample_freq } 1 sample_type TIME|CPU|PERIOD|RAW read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING disabled 1 inherit 1 enable_on_exec 1 exclude_guest 1 ... After: $ sudo perf stat -e 'raw_syscalls:sys_enter' -vv ls ------------------------------------------------------------ perf_event_attr: type 2 size 112 config 0x11 read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING disabled 1 inherit 1 enable_on_exec 1 exclude_guest 1 ... Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1448465815-27404-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 7 +++++++ 1 file changed, 7 insertions(+) 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) attr->inherit = !no_inherit; + /* + * Some events get initialized with sample_(period/type) set, + * like tracepoints. Clear it up for counting. + */ + attr->sample_period = 0; + attr->sample_type = 0; + if (target__has_cpu(&target)) return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); From dcdd184b60c3943fb678dcbaf899a26f845901ad Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 25 Nov 2015 16:36:55 +0100 Subject: [PATCH 12/13] perf evlist: Display WEIGHT sample type bit Adding WIEGHT bit_name call to display sample_type properly. $ perf evlist -v cpu/mem-loads/pp: ...SNIP... sample_type: IP|TID|TIME|ADDR|ID|CPU|DATA_SRC|WEIGHT ... Signed-off-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1448465815-27404-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 1 + 1 file changed, 1 insertion(+) 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) bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), + bit_name(WEIGHT), { .name = NULL, } }; #undef bit_name From 43798bf37215fe242e592fd4605d804e2da0781b Mon Sep 17 00:00:00 2001 From: He Kuang Date: Tue, 24 Nov 2015 13:36:08 +0000 Subject: [PATCH 13/13] bpf tools: Add helper function for updating bpf maps elements Add bpf_map_update_elem() helper function which calls the sys_bpf syscall to update elements in bpf maps. Upcoming patches will use it to adjust data in map through the perf command line. Signed-off-by: He Kuang Cc: Alexei Starovoitov Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Wang Nan Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1448372181-151723-4-git-send-email-wangnan0@huawei.com Signed-off-by: Wang Nan Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/bpf/bpf.c | 14 ++++++++++++++ tools/lib/bpf/bpf.h | 2 ++ 2 files changed, 16 insertions(+) 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, log_buf[0] = 0; return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); } + +int bpf_map_update_elem(int fd, void *key, void *value, + u64 flags) +{ + union bpf_attr attr; + + bzero(&attr, sizeof(attr)); + attr.map_fd = fd; + attr.key = ptr_to_u64(key); + attr.value = ptr_to_u64(value); + attr.flags = flags; + + return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); +} 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, u32 kern_version, char *log_buf, size_t log_buf_sz); +int bpf_map_update_elem(int fd, void *key, void *value, + u64 flags); #endif