Skip to contentSkip to conversation

perf/core improvements and fixes

GIT PULL In review Arnaldo Carvalho de Melo 3 participants 19 messages Nov 19, 2014 – Nov 20, 2014 perf events

lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi 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(-)
author maintainer
#1 lore raw

PATCH 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().

Cc Aravinda Prasad <[email protected]>
Cc Brendan Gregg <[email protected]>
Cc Hemant Kumar <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Oleg Nesterov <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Srikar Dronamraju <[email protected]>
Cc Vasant Hegde <[email protected]>
---
 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
index dd2a3e52ada1..e8d79e5bfaf7 100644
@@ -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
index 666a3bd4f64e..8236319514d5 100644
@@ -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
index 05fab7a188dc..b20e40c74468 100644
@@ -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
index 7dc44cfe25b3..76d23d83eae5 100644
@@ -154,7 +154,6 @@ extern void set_die_routine(void (*routine)(const char *err, va_list params) NOR
 
 extern 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
author maintainer
#2 lore raw

PATCH 2/16 perf tools: Clean up libelf feature support code

In reply to Arnaldo Carvalho de Melo

From: 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
index aecf61dcd754..478efa9b2364 100644
@@ -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
index 79f906c7124e..5d4b039fe1ed 100644
@@ -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
author maintainer
#3 lore raw

PATCH 3/16 perf symbols: Fallback to kallsyms when using the minimal 'ELF' loader

In reply to Arnaldo Carvalho de Melo

From: 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.

Cc Adrian Hunter <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/symbol-minimal.c | 1 -
 1 file changed, 1 deletion(-)
tools/perf/util/symbol-minimal.c +0 -1
index c9541fea9514..fa585c63f56a 100644
@@ -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
author maintainer
#4 lore raw

PATCH 4/16 perf test: fix typo in python test

In reply to Arnaldo Carvalho de Melo

From: WANG Chao <[email protected]>

Library loading in python syntax should be 'import perf', not 'use perf'.

Cc Adrian Hunter <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jean Pihet <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
---
 tools/perf/tests/builtin-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/tests/builtin-test.c +1 -1
index 162c978f1491..4b7d9ab0f049 100644
@@ -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
author maintainer
#5 lore raw

PATCH 5/16 perf tools: Fix annotation with kcore

In reply to Arnaldo Carvalho de Melo

From: 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
index 7dabde14ea54..873c8778db20 100644
@@ -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
author maintainer
#6 lore raw

PATCH 6/16 perf callchain: Factor out adding new call chain entries

In reply to Arnaldo Carvalho de Melo

From: 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
index 52e94902afb1..84390eecab06 100644
@@ -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
author maintainer
#7 lore raw

PATCH 7/16 perf callchain: Use al.addr to set up call chain

In reply to Arnaldo Carvalho de Melo

From: 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
index 84390eecab06..d97309c87bd6 100644
@@ -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
author maintainer
#8 lore raw

PATCH 8/16 perf callchain: Use a common function to resolve symbol or name

In reply to Arnaldo Carvalho de Melo

From: 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
index cfb976b3de3a..12c17c5a3d68 100644
@@ -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
index fc654fb77ace..4b3585eed1e8 100644
@@ -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
index 15b451acbde6..dfcbc90146ef 100644
@@ -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
index 00229809a904..38da69c8c1ff 100644
@@ -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
index 3caccc2c173c..3e1ed15d11f1 100644
@@ -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
author maintainer
#9 lore raw

PATCH 9/16 perf tools: Only print base source file for srcline

In reply to Arnaldo Carvalho de Melo

From: 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
index f3e4bc5fe5d2..77c180637138 100644
@@ -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
author maintainer
#10 lore raw

PATCH 10/16 perf annotate: Support source line numbers in annotate

In reply to Arnaldo Carvalho de Melo

From: 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
index f0697a3aede0..1e0a2fd80115 100644
@@ -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, int
 	if (!*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
index 873c8778db20..e5670f1af737 100644
@@ -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
index 112d6e268150..0784a9420528 100644
@@ -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
author maintainer
#11 lore raw

PATCH 11/16 perf hists: Fix up srcline histogram key formatting

In reply to Arnaldo Carvalho de Melo

From: 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

Cc Adrian Hunter <[email protected]>
Cc Andi Kleen <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/sort.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/sort.c +1 -1
index 9402885a77f3..82a5596241a7 100644
@@ -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
#12 lore raw

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

author maintainer
#13 lore raw

PATCH 12/16 perf diff: Add missing handler for PERF_RECORD_MMAP2 events

In reply to Arnaldo Carvalho de Melo

From: 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
index 25114c9a6801..1ce425d101a9 100644
@@ -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
author maintainer
#14 lore raw

PATCH 13/16 perf evsel: Fix ftrace:function event recording

In reply to Arnaldo Carvalho de Melo

From: 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
index 34344ffa79ca..f2dc91fb87fa 100644
@@ -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
author maintainer
#15 lore raw

PATCH 14/16 perf evlist: Do not poll events that use the system_wide flag

In reply to Arnaldo Carvalho de Melo

From: 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
index 7e23dae54f1d..cfbe2b99b9aa 100644
@@ -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
author maintainer
#16 lore raw

PATCH 15/16 perf tools: Add perf-read-vdso32 and perf-read-vdsox32 to .gitignore

In reply to Arnaldo Carvalho de Melo

From: 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
index 717221e98450..40399c3d97d6 100644
@@ -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
author maintainer
#17 lore raw

PATCH 16/16 perf tools: Only override the default :tid comm entry

In reply to Arnaldo Carvalho de Melo

From: 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
index a2157f0ef1df..9ebc8b1f9be5 100644
@@ -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
#18 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 109 lines · Arnaldo Carvalho de Melo

Hi 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 ++++++
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