perf/core improvements and fixes
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit 2565711fb7d7c28e0cd93c8971b520d1b10b857c:
perf: Improve the perf_sample_data struct layout (2014-11-16 11:42:04 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to a84808083688d82d7f1e5786ccf5df0ff7d448cb:
perf tools: Only override the default :tid comm entry (2014-11-19 12:37:26 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
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:
- Do not poll events that use the system_wide flag (Adrian Hunter)
- Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore (Adrian Hunter)
perf tools: 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)
----------------------------------------------------------------
Adrian Hunter (4):
perf tools: Fix annotation with kcore
perf evlist: Do not poll events that use the system_wide flag perf tools: Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore perf tools: Only override the default :tid comm entry
Andi Kleen (5):
perf callchain: Factor out adding new call chain entries perf callchain: Use al.addr to set up call chain perf callchain: Use a common function to resolve symbol or name perf tools: Only print base source file for srcline perf annotate: Support source line numbers in annotate
Arnaldo Carvalho de Melo (2):
perf symbols: Fallback to kallsyms when using the minimal 'ELF' loader perf hists: Fix up srcline histogram key formatting
Jiri Olsa (1):
perf evsel: Fix ftrace:function event recording
Kan Liang (1):
perf diff: Add missing handler for PERF_RECORD_MMAP2 events
Namhyung Kim (2):
perf build-id: Move disable_buildid_cache() to util/build-id.c perf tools: Clean up libelf feature support code
WANG Chao (1):
perf test: fix typo in python test
tools/perf/.gitignore | 2 ++ tools/perf/Makefile.perf | 2 -- tools/perf/builtin-diff.c | 1 + tools/perf/config/Makefile | 5 ++-- tools/perf/tests/builtin-test.c | 2 +- tools/perf/ui/browsers/annotate.c | 13 +++++++++- tools/perf/ui/browsers/hists.c | 17 ------------- tools/perf/ui/gtk/hists.c | 11 +-------- tools/perf/ui/stdio/hist.c | 23 +++++++----------- tools/perf/util/annotate.c | 32 ++++++++++++++++++++---- tools/perf/util/annotate.h | 1 + tools/perf/util/build-id.c | 11 +++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/callchain.c | 19 +++++++++++++++ tools/perf/util/callchain.h | 3 +++ tools/perf/util/evlist.c | 10 +++++++- tools/perf/util/evsel.c | 8 ++++++ tools/perf/util/header.c | 10 +------- tools/perf/util/machine.c | 51 ++++++++++++++++++++++++--------------- tools/perf/util/sort.c | 2 +- tools/perf/util/srcline.c | 2 +- tools/perf/util/symbol-minimal.c | 1 - tools/perf/util/thread.c | 5 ++-- tools/perf/util/util.h | 1 - 24 files changed, 145 insertions(+), 88 deletions(-)
Arnaldo Carvalho de Melo
maintainerPATCH 1/16 perf build-id: Move disable_buildid_cache() to util/build-id.c
From: Namhyung Kim <[email protected]>
Also move static variable no_buildid_cache and check it in the perf_session_cache_build_ids().
--- tools/perf/util/build-id.c | 11 +++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/header.c | 10 +--------- tools/perf/util/util.h | 1 - 4 files changed, 13 insertions(+), 10 deletions(-)
tools/perf/util/build-id.c +11 -0
@@ -18,6 +18,9 @@#include "header.h" #include "vdso.h" + +static bool no_buildid_cache; + int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample,
@@ -251,6 +254,11 @@ int dsos__hit_all(struct perf_session *session)return 0 ; } +void disable_buildid_cache (void ) +{ + no_buildid_cache = true; +} +int build_id_cache__add_s (const char *sbuild_id,const char *debugdir,const char *name,bool is_kallsyms,bool is_vdso) {
@@ -404,6 +412,9 @@ int perf_session__cache_build_ids(struct perf_session *session)int ret;char debugdir[PATH_MAX ]; +if (no_buildid_cache) +return 0 ; +snprintf (debugdir,sizeof (debugdir),"%s" , buildid_dir);if (mkdir (debugdir,0755 ) !=0 && errno !=EEXIST )
tools/perf/util/build-id.h +1 -0
@@ -25,5 +25,6 @@ int perf_session__cache_build_ids(struct perf_session *session);int build_id_cache__add_s (const char *sbuild_id,const char *debugdir,const char *name,bool is_kallsyms,bool is_vdso);int build_id_cache__remove_s (const char *sbuild_id,const char *debugdir); +void disable_buildid_cache (void );#endif
tools/perf/util/header.c +1 -9
@@ -24,8 +24,6 @@#include "build-id.h" #include "data.h" -static bool no_buildid_cache = false; -static u32 header_argc;static const char **header_argv;
@@ -191,8 +189,7 @@ static int write_build_id(int fd, struct perf_header *h,pr_debug ("failed to write buildid table\n" );return err; } -if (!no_buildid_cache) -perf_session__cache_build_ids (session); +perf_session__cache_build_ids (session);return 0 ; }
@@ -2791,8 +2788,3 @@ int perf_event__process_build_id(struct perf_tool *tool __maybe_unused, session);return 0 ; } - -void disable_buildid_cache (void ) -{ - no_buildid_cache = true; -}
tools/perf/util/util.h +0 -1
@@ -154,7 +154,6 @@ extern void set_die_routine(void (*routine)(const char *err, va_list params) NORextern int prefixcmp (const char *str,const char *prefix);extern void set_buildid_dir (void ); -extern void disable_buildid_cache (void );static inline const char *skip_prefix (const char *str,const char *prefix) {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/16 perf tools: Clean up libelf feature support code
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Current EXTLIBS contains -lelf by default and removes it when libelf is not detected.
This is little bit confusing since we can now build perf without libelf so there's no need to handle it differently than other libraries.
--- tools/perf/Makefile.perf | 2 -- tools/perf/config/Makefile | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-)
tools/perf/Makefile.perf +0 -2
@@ -497,8 +497,6 @@ ifneq ($(OUTPUT),) endif ifdef NO_LIBELF -EXTLIBS := $(filter-out -lelf,$(EXTLIBS)) - # Remove ELF/DWARF dependent codes LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS)) LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
tools/perf/config/Makefile +3 -2
@@ -150,7 +150,7 @@ CFLAGS += -std=gnu99 # adding assembler files missing the .GNU-stack linker note. LDFLAGS += -Wl,-z,noexecstack -EXTLIBS = -lelf -lpthread -lrt -lm -ldl +EXTLIBS = -lpthread -lrt -lm -ldl ifneq ($(OUTPUT),) OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
@@ -354,6 +354,7 @@ endif # NO_LIBELF ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT + EXTLIBS += -lelf ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
@@ -373,7 +374,7 @@ ifndef NO_LIBELF else CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) - EXTLIBS += -lelf -ldw + EXTLIBS += -ldw endif # PERF_HAVE_DWARF_REGS endif # NO_DWARF endif # NO_LIBELF
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/16 perf symbols: Fallback to kallsyms when using the minimal 'ELF' loader
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
The minimal ELF loader should not return 1 when it manages to read the vmlinux build-id, it should instead return 0, meaning that it hasn't loaded any symbols, since it doesn't parses ELF at all.
That way, the main symbol.c routines will understand that it is necessary to continue looking for a file with symbols, and when no libelf is linked, that means it will eventually try kallsyms.
--- tools/perf/util/symbol-minimal.c | 1 - 1 file changed, 1 deletion(-)
tools/perf/util/symbol-minimal.c +0 -1
@@ -341,7 +341,6 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) >0 ) {dso__set_build_id (dso, build_id); -return 1 ; }return 0 ; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/16 perf test: fix typo in python test
In reply to Arnaldo Carvalho de MeloFrom: WANG Chao <[email protected]>
Library loading in python syntax should be 'import perf', not 'use perf'.
--- tools/perf/tests/builtin-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/tests/builtin-test.c +1 -1
@@ -85,7 +85,7 @@ static struct test { .func = test__hists_link, }, { - .desc = "Try 'use perf' in python, checking link problems", + .desc = "Try 'import perf' in python, checking link problems", .func = test__python_use, }, {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/16 perf tools: Fix annotation with kcore
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Patch "perf tools: Fix build-id matching on vmlinux" breaks annotation with kcore. The problem is that symbol__annotate() first gets the filename based on the build-id which was previously not set.
This patch provides a quick fix, however there should probably be only one way to determine the filename. e.g. symbol__annotate() should use the same way as dso__data_fd().
--- tools/perf/util/annotate.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/annotate.c +2 -0
@@ -915,6 +915,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)return -ENOMEM ; } goto fallback; + }else if (dso__is_kcore (dso)) { + goto fallback; }else if (readlink (symfs_filename, command,sizeof (command)) <0 ||strstr (command,"[kernel.kallsyms]" ) ||access (symfs_filename,R_OK )) {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/16 perf callchain: Factor out adding new call chain entries
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Move the code to resolve and add a new callchain entry into a new add_callchain_ip function. This will be used in the next patches to add LBRs too.
No change in behavior.
--- tools/perf/util/machine.c | 51 +++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 19 deletions(-)
tools/perf/util/machine.c +32 -19
@@ -1381,6 +1381,34 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,return mi; } +static int add_callchain_ip (struct thread *thread, +struct symbol **parent, +struct addr_location *root_al, +int cpumode, +u64 ip) +{ +struct addr_location al; + + al.filtered =0 ; + al.sym =NULL ; +thread__find_addr_location (thread, cpumode,MAP__FUNCTION , + ip, &al); +if (al.sym !=NULL ) { +if (sort__has_parent && !*parent && +symbol__match_regex (al.sym, &parent_regex)) + *parent = al.sym; +else if (have_ignore_callees && root_al && +symbol__match_regex (al.sym, &ignore_callees_regex)) { +/* Treat this symbol as the root, +forgetting its callees. */ + *root_al = al; +callchain_cursor_reset (&callchain_cursor); + } + } + +return callchain_cursor_append (&callchain_cursor, ip, al.map, al.sym); +} +struct branch_info *sample__resolve_bstack (struct perf_sample *sample,struct addr_location *al) {
@@ -1427,7 +1455,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,for (i =0 ; i < chain_nr; i++) {u64 ip; -struct addr_location al;if (callchain_param.order ==ORDER_CALLEE ) j = i;
@@ -1464,24 +1491,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,continue ; } - al.filtered =0 ; -thread__find_addr_location (thread, cpumode, -MAP__FUNCTION , ip, &al); -if (al.sym !=NULL ) { -if (sort__has_parent && !*parent && -symbol__match_regex (al.sym, &parent_regex)) - *parent = al.sym; -else if (have_ignore_callees && root_al && -symbol__match_regex (al.sym, &ignore_callees_regex)) { -/* Treat this symbol as the root, -forgetting its callees. */ - *root_al = al; -callchain_cursor_reset (&callchain_cursor); - } - } - - err =callchain_cursor_append (&callchain_cursor, - ip, al.map, al.sym); + err =add_callchain_ip (thread, parent, root_al, + cpumode, ip); +if (err == -EINVAL ) +break ;if (err)return err; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/16 perf callchain: Use al.addr to set up call chain
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Use the relative address, this makes get_srcline work correctly in the end.
--- tools/perf/util/machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/machine.c +1 -1
@@ -1406,7 +1406,7 @@ static int add_callchain_ip(struct thread *thread, } } -return callchain_cursor_append (&callchain_cursor, ip, al.map, al.sym); +return callchain_cursor_append (&callchain_cursor, al.addr, al.map, al.sym); } struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/16 perf callchain: Use a common function to resolve symbol or name
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Refactor the duplicated code to resolve the symbol name or the address of a symbol into a single function.
Used in next patch to add common functionality.
--- tools/perf/ui/browsers/hists.c | 17 ----------------- tools/perf/ui/gtk/hists.c | 11 +---------- tools/perf/ui/stdio/hist.c | 23 +++++++++-------------- tools/perf/util/callchain.c | 19 +++++++++++++++++++ tools/perf/util/callchain.h | 3 +++ 5 files changed, 32 insertions(+), 41 deletions(-)
tools/perf/ui/browsers/hists.c +0 -17
@@ -463,23 +463,6 @@ out:return key; } -static char *callchain_list__sym_name (struct callchain_list *cl, -char *bf,size_t bfsize,bool show_dso) -{ -int printed; - -if (cl->ms.sym) - printed =scnprintf (bf, bfsize,"%s" , cl->ms.sym->name); -else - printed =scnprintf (bf, bfsize,"%#" PRIx64, cl->ip); - -if (show_dso) -scnprintf (bf + printed, bfsize - printed," %s" , - cl->ms.map ? cl->ms.map->dso->short_name :"unknown" ); - -return bf; -} -struct callchain_print_arg {/* for hists browser */ off_t row_offset;
tools/perf/ui/gtk/hists.c +1 -10
@@ -89,15 +89,6 @@ void perf_gtk__init_hpp(void) perf_gtk__hpp_color_overhead_acc; } -static void callchain_list__sym_name (struct callchain_list *cl, -char *bf,size_t bfsize) -{ -if (cl->ms.sym) -scnprintf (bf, bfsize,"%s" , cl->ms.sym->name); -else -scnprintf (bf, bfsize,"%#" PRIx64, cl->ip); -} -static void perf_gtk__add_callchain (struct rb_root *root,GtkTreeStore *store,GtkTreeIter *parent,int col,u64 total) {
@@ -128,7 +119,7 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,scnprintf (buf,sizeof (buf),"%5.2f%%" , percent);gtk_tree_store_set (store, &iter,0 , buf,-1 ); -callchain_list__sym_name (chain, buf,sizeof (buf)); +callchain_list__sym_name (chain, buf,sizeof (buf), false);gtk_tree_store_set (store, &iter, col, buf,-1 );if (need_new_parent) {
tools/perf/ui/stdio/hist.c +9 -14
@@ -41,6 +41,7 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, {int i;size_t ret =0 ; +char bf[1024 ]; ret +=callchain__fprintf_left_margin (fp, left_margin);for (i =0 ; i < depth; i++) {
@@ -56,11 +57,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, }else ret +=fprintf (fp,"%s" ," " ); } -if (chain->ms.sym) - ret +=fprintf (fp,"%s\n" , chain->ms.sym->name); -else - ret +=fprintf (fp,"0x%0" PRIx64"\n" , chain->ip); - +fputs (callchain_list__sym_name (chain, bf,sizeof (bf), false), fp); +fputc ('\n' , fp);return ret; }
@@ -168,6 +166,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,struct rb_node *node;int i =0 ;int ret =0 ; +char bf[1024 ];/* * 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, }else ret +=callchain__fprintf_left_margin (fp, left_margin); -if (chain->ms.sym) - ret +=fprintf (fp," %s\n" , chain->ms.sym->name); -else - ret +=fprintf (fp," %p\n" , (void *)(long )chain->ip); + ret +=fprintf (fp,"%s\n" ,callchain_list__sym_name (chain, bf,sizeof (bf), + false));if (++entries_printed == callchain_param.print_limit)break ;
@@ -219,6 +216,7 @@ static size_t __callchain__fprintf_flat(FILE *fp, struct callchain_node *node, {struct callchain_list *chain;size_t ret =0 ; +char bf[1024 ];if (!node)return 0 ;
@@ -229,11 +227,8 @@ static size_t __callchain__fprintf_flat(FILE *fp, struct callchain_node *node,list_for_each_entry (chain, &node->val, list) {if (chain->ip >=PERF_CONTEXT_MAX )continue ; -if (chain->ms.sym) - ret +=fprintf (fp," %s\n" , chain->ms.sym->name); -else - ret +=fprintf (fp," %p\n" , - (void *)(long )chain->ip); + ret +=fprintf (fp," %s\n" ,callchain_list__sym_name (chain, + bf,sizeof (bf), false)); }return ret;
tools/perf/util/callchain.c +19 -0
@@ -808,3 +808,22 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * out:return 1 ; } + +char *callchain_list__sym_name (struct callchain_list *cl, +char *bf,size_t bfsize,bool show_dso) +{ +int printed; + +if (cl->ms.sym) { + printed =scnprintf (bf, bfsize,"%s" , cl->ms.sym->name); + }else + printed =scnprintf (bf, bfsize,"%#" PRIx64, cl->ip); + +if (show_dso) +scnprintf (bf + printed, bfsize - printed," %s" , + cl->ms.map ? + cl->ms.map->dso->short_name : +"unknown" ); + +return bf; +}
tools/perf/util/callchain.h +3 -0
@@ -193,4 +193,7 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, }#endif +char *callchain_list__sym_name (struct callchain_list *cl, +char *bf,size_t bfsize,bool show_dso); +#endif /* __PERF_CALLCHAIN_H */
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/16 perf tools: Only print base source file for srcline
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
For perf report with --sort srcline only print the base source file name. This makes the results generally fit much better to the screen. The path is usually not that useful anyways because it is often from different systems.
--- tools/perf/util/srcline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/srcline.c +1 -1
@@ -274,7 +274,7 @@ char *get_srcline(struct dso *dso, unsigned long addr)if (!addr2line (dso_name, addr, &file, &line, dso)) goto out; -if (asprintf (&srcline,"%s:%u" , file, line) <0 ) { +if (asprintf (&srcline,"%s:%u" ,basename (file), line) <0 ) {free (file); goto out; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/16 perf annotate: Support source line numbers in annotate
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
With srcline key/sort'ing it's useful to have line numbers in the annotate window. This patch implements this.
Use objdump -l to request the line numbers and save them in the line structure. Then the browser displays them for source lines.
The line numbers are not displayed by default, but can be toggled on with 'k'
There is one unfortunate problem with this setup. For lines not containing source and which are outside functions objdump -l reports line numbers off by a few: it always reports the first line number in the next function even for lines that are outside the function.
I haven't found a nice way to detect/correct this. Probably objdump has to be fixed.
See https://sourceware.org/bugzilla/show_bug.cgi?id=16433
The line numbers are still useful even with these problems, as most are correct and the ones which are not are nearby.
v2: Fix help text. Handle (discriminator...) output in objdump. Left align the line numbers.
--- tools/perf/ui/browsers/annotate.c | 13 ++++++++++++- tools/perf/util/annotate.c | 30 +++++++++++++++++++++++++----- tools/perf/util/annotate.h | 1 + 3 files changed, 38 insertions(+), 6 deletions(-)
tools/perf/ui/browsers/annotate.c +12 -1
@@ -27,6 +27,7 @@ static struct annotate_browser_opt {bool hide_src_code, use_offset, jump_arrows, + show_linenr, show_nr_jumps; } annotate_browser__opts = { .use_offset = true,
@@ -128,7 +129,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, intif (!*dl->line)slsmg_write_nstring (" " , width - pcnt_width);else if (dl->offset ==-1 ) { - printed =scnprintf (bf,sizeof (bf),"%*s " , +if (dl->line_nr && annotate_browser__opts.show_linenr) + printed =scnprintf (bf,sizeof (bf),"%-*d " , + ab->addr_width +1 , dl->line_nr); +else + printed =scnprintf (bf,sizeof (bf),"%*s " , ab->addr_width," " );slsmg_write_nstring (bf, printed);slsmg_write_nstring (dl->line, width - printed - pcnt_width +1 );
@@ -733,6 +738,7 @@ static int annotate_browser__run(struct annotate_browser *browser,"o Toggle disassembler output/simplified view\n" "s Toggle source code view\n" "/ Search string\n" +"k Toggle line numbers\n" "r Run available scripts\n" "? Search string backwards\n");continue ;
@@ -741,6 +747,10 @@ static int annotate_browser__run(struct annotate_browser *browser,script_browse (NULL );continue ; } +case 'k' : + annotate_browser__opts.show_linenr = + !annotate_browser__opts.show_linenr; +break ;case 'H' : nd = browser->curr_hot;break ;
@@ -984,6 +994,7 @@ static struct annotate_config { } annotate__configs[] = {ANNOTATE_CFG (hide_src_code),ANNOTATE_CFG (jump_arrows), +ANNOTATE_CFG (show_linenr),ANNOTATE_CFG (show_nr_jumps), ANNOTATE_CFG(use_offset), };
tools/perf/util/annotate.c +25 -5
@@ -17,11 +17,13 @@#include "debug.h" #include "annotate.h" #include "evsel.h" +#include <regex.h> #include <pthread.h> #include <linux/bitops.h> const char *disassembler_style;const char *objdump_path; +static regex_t file_lineno;static struct ins *ins__find (const char *name);static int disasm_line__parse (char *line,char **namep,char **rawp);
@@ -570,13 +572,15 @@ out_free_name:return -1 ; } -static struct disasm_line *disasm_line__new (s64 offset,char *line,size_t privsize) +static struct disasm_line *disasm_line__new (s64 offset,char *line, +size_t privsize,int line_nr) {struct disasm_line *dl =zalloc (sizeof (*dl) + privsize);if (dl !=NULL ) { dl->offset = offset; dl->line =strdup (line); + dl->line_nr = line_nr;if (dl->line ==NULL ) goto out_delete;
@@ -788,13 +792,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st* The ops.raw part will be parsed further according to type of the instruction. */ static int symbol__parse_objdump_line (struct symbol *sym,struct map *map, -FILE *file,size_t privsize) +FILE *file,size_t privsize, +int *line_nr) {struct annotation *notes =symbol__annotation (sym);struct disasm_line *dl;char *line =NULL , *parsed_line, *tmp, *tmp2, *c;size_t line_len;s64 line_ip, offset =-1 ; +regmatch_t match[2 ];if (getline (&line, &line_len, file) <0 )return -1 ;
@@ -812,6 +818,12 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, line_ip =-1 ; parsed_line = line; +/* /filename:linenr ? Save line number and ignore. */ +if (regexec (&file_lineno, line,2 , match,0 ) ==0 ) { + *line_nr =atoi (line + match[1 ].rm_so); +return 0 ; + } +/* * Strip leading spaces: */
@@ -842,8 +854,9 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, parsed_line = tmp2 +1 ; } - dl =disasm_line__new (offset, parsed_line, privsize); + dl =disasm_line__new (offset, parsed_line, privsize, *line_nr);free (line); + (*line_nr)++;if (dl ==NULL )return -1 ;
@@ -869,6 +882,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,return 0 ; } +static __attribute__((constructor))void symbol__init_regexpr (void ) +{ +regcomp (&file_lineno,"^/[^:]+:([0-9]+)" ,REG_EXTENDED ); +} +static void delete_last_nop (struct symbol *sym) {struct annotation *notes =symbol__annotation (sym);
@@ -904,6 +922,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)char symfs_filename[PATH_MAX ];struct kcore_extract kce;bool delete_extract = false; +int lineno =0 ;if (filename)symbol__join_symfs (symfs_filename, filename);
@@ -984,7 +1003,7 @@ fallback: snprintf(command, sizeof(command), "%s %s%s --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 - " -d %s %s -C %s 2>/dev/null|grep -v %s|expand", + " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand", objdump_path ? objdump_path : "objdump", disassembler_style ? "-M " : "", disassembler_style ? disassembler_style : "",
@@ -1001,7 +1020,8 @@ fallback: goto out_free_filename;while (!feof (file)) -if (symbol__parse_objdump_line (sym, map, file, privsize) <0 ) +if (symbol__parse_objdump_line (sym, map, file, privsize, + &lineno) <0 )break ;/*
tools/perf/util/annotate.h +1 -0
@@ -58,6 +58,7 @@ struct disasm_line {char *line;char *name;struct ins *ins; +int line_nr;struct ins_operands ops; };
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 11/16 perf hists: Fix up srcline histogram key formatting
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
Problem introduced in:
commit 5b5916696051 "perf report: Honor column width setting"
Where the left justification signal was after the width, which ended up, when the width was, say, 11, always printing:
%11.11-s
Instead of src:line left justified and limited to 11 chars.
Resulting in a like:
70.93% %11.11-s [.] f2 tcall
When it should instead be:
70.93% tcall.c:5 [.] f2 tcall
--- tools/perf/util/sort.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/sort.c +1 -1
@@ -309,7 +309,7 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)static int hist_entry__srcline_snprintf (struct hist_entry *he,char *bf,size_t size,unsigned int width) { -return repsep_snprintf (bf, size,"%*.*-s" , width, width, he->srcline); +return repsep_snprintf (bf, size,"%-*.*s" , width, width, he->srcline); }struct sort_entry sort_srcline = {
Signature · 1 line
1.9.3
Re: [PATCH 11/16] perf hists: Fix up srcline histogram key formatting
Quoted 5 lines · Arnaldo Carvalho de Melo
From: Arnaldo Carvalho de Melo <[email protected]>
Problem introduced in:
commit
5b5916696051"perf report: Honor column width setting"
Thanks!
I'll also check what happens with --gtk.
-Andi
Arnaldo Carvalho de Melo
maintainerPATCH 12/16 perf diff: Add missing handler for PERF_RECORD_MMAP2 events
In reply to Arnaldo Carvalho de MeloFrom: Kan Liang <[email protected]>
Without mmap2, perf diff fails to find the symbol name. The default symbol sort key doesn't work well.
--- tools/perf/builtin-diff.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-diff.c +1 -0
@@ -357,6 +357,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,static struct perf_tool tool = { .sample = diff__process_sample_event, .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork,
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 13/16 perf evsel: Fix ftrace:function event recording
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Following patch fails (-EINVAL) ftrace:function with enabled user space callchains:
cfa77bc4af2c perf: Disallow user-space callchains for function trace events
We need to follow in perf tool itself and explicitly set the perf_event_attr::exclude_callchain_user flag for ftrace:function event.
--- tools/perf/util/evsel.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/perf/util/evsel.c +8 -0
@@ -658,6 +658,14 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) attr->mmap_data = track; } +/* +* We don't allow user space callchains for function trace +* event, due to issues with page faults while tracing page +* fault handler and its overall trickiness nature. +*/ +if (perf_evsel__is_function_event (evsel)) + evsel->attr.exclude_callchain_user =1 ; +if (callchain_param.enabled && !evsel->no_aux_samples)perf_evsel__config_callgraph (evsel);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 14/16 perf evlist: Do not poll events that use the system_wide flag
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
The system_wide flag causes a selected event to be opened always without a pid.
Consequently it will never get a POLLHUP, but it is used for tracking in combination with other events, so it should not need to be polled anyway.
Therefore don't add it for polling.
--- tools/perf/util/evlist.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
tools/perf/util/evlist.c +9 -1
@@ -816,7 +816,15 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,perf_evlist__mmap_get (evlist, idx); } -if (__perf_evlist__add_pollfd (evlist, fd, idx) <0 ) { +/* +* The system_wide flag causes a selected event to be opened +* always without a pid. Consequently it will never get a +* POLLHUP, but it is used for tracking in combination with +* other events, so it should not need to be polled anyway. +* Therefore don't add it for polling. +*/ +if (!evsel->system_wide && +__perf_evlist__add_pollfd (evlist, fd, idx) <0 ) {perf_evlist__mmap_put (evlist, idx);return -1 ; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 15/16 perf tools: Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Recently added executables Add perf-read-vdso32 and perf-read-vdsox32 need to be added to .gitignore.
--- tools/perf/.gitignore | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/.gitignore +2 -0
@@ -2,6 +2,8 @@ PERF-CFLAGS PERF-GUI-VARS PERF-VERSION-FILE perf +perf-read-vdso32 +perf-read-vdsox32 perf-help perf-record perf-report
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 16/16 perf tools: Only override the default :tid comm entry
In reply to Arnaldo Carvalho de MeloFrom: Adrian Hunter <[email protected]>
Events may still be ordered even if there are no timestamps e.g. if the data is recorded per-thread.
Also synthesized COMM events have a timestamp of zero.
Consequently it is better to keep comm entries even if they have a timestamp of zero.
However, when a struct thread is created the command string is not known and a comm entry with a string of the form ":<tid>" is used.
In that case thread->comm_set is false and the comm entry should be overridden.
--- tools/perf/util/thread.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
tools/perf/util/thread.c +2 -3
@@ -103,15 +103,14 @@ struct comm *thread__exec_comm(const struct thread *thread)return last; } -/* CHECKME: time should always be 0 if event aren't ordered */ int __thread__set_comm (struct thread *thread,const char *str,u64 timestamp,bool exec) {struct comm *new, *curr =thread__comm (thread);int err; -/* Override latest entry if it had no specific time coverage */ -if (!curr->start && !curr->exec) { +/* Override the default :tid entry */ +if (!thread->comm_set) { err =comm__override (curr, str, timestamp, exec);if (err)return err;
Signature · 1 line
1.9.3
Quoted 109 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit
2565711fb7d7c28e0cd93c8971b520d1b10b857c:perf: Improve the
perf_sample_datastruct layout (2014-11-16 11:42:04 +0100)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingofor you to fetch changes up to
a84808083688d82d7f1e5786ccf5df0ff7d448cb:perf tools: Only override the default :tid comm entry (2014-11-19 12:37:26 -0300)
----------------------------------------------------------------
perf/core improvements and fixes: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_MMAP2events 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:
- Do not poll events that use the
system_wideflag (Adrian Hunter)- Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore (Adrian Hunter)
perf tools: 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()toutil/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 <[email protected]>----------------------------------------------------------------
Adrian Hunter (4):
perf tools: Fix annotation with kcore
perf evlist: Do not poll events that use thesystem_wideflag perf tools: Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore perf tools: Only override the default :tid comm entryAndi Kleen (5):
perf callchain: Factor out adding new call chain entries perf callchain: Use al.addr to set up call chain perf callchain: Use a common function to resolve symbol or name perf tools: Only print base source file for srcline perf annotate: Support source line numbers in annotateArnaldo Carvalho de Melo (2):
perf symbols: Fallback to kallsyms when using the minimal 'ELF' loader perf hists: Fix up srcline histogram key formattingJiri Olsa (1):
perf evsel: Fix ftrace:function event recordingKan Liang (1):
perf diff: Add missing handler forPERF_RECORD_MMAP2eventsNamhyung Kim (2):
perf build-id: Movedisable_buildid_cache()toutil/build-id.cperf tools: Clean up libelf feature support codeWANG Chao (1):
perf test: fix typo in python testtools/perf/.gitignore | 2 ++ tools/perf/Makefile.perf | 2 -- tools/perf/builtin-diff.c | 1 + tools/perf/config/Makefile | 5 ++-- tools/perf/tests/builtin-test.c | 2 +- tools/perf/ui/browsers/annotate.c | 13 +++++++++- tools/perf/ui/browsers/hists.c | 17 ------------- tools/perf/ui/gtk/hists.c | 11 +-------- tools/perf/ui/stdio/hist.c | 23 +++++++----------- tools/perf/util/annotate.c | 32 ++++++++++++++++++++---- tools/perf/util/annotate.h | 1 + tools/perf/util/build-id.c | 11 +++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/callchain.c | 19 +++++++++++++++ tools/perf/util/callchain.h | 3 +++ tools/perf/util/evlist.c | 10 +++++++- tools/perf/util/evsel.c | 8 ++++++
Quoted 8 lines
tools/perf/util/header.c | 10 +------- tools/perf/util/machine.c | 51 ++++++++++++++++++++++++--------------- tools/perf/util/sort.c | 2 +- tools/perf/util/srcline.c | 2 +- tools/perf/util/symbol-minimal.c | 1 - tools/perf/util/thread.c | 5 ++-- tools/perf/util/util.h | 1 - 24 files changed, 145 insertions(+), 88 deletions(-)
Pulled into tip:perf/core, thanks a lot Arnaldo!
Ingo