Skip to contentSkip to conversation

perf tools: Fix for cases where cpumode is incorrect or insufficient

PATCH In review Adrian Hunter 4 participants 17 messages Nov 6, 2018 – Dec 18, 2018 perf events

lore
Share & tools
lore

Adrian Hunter

author reviewer
#0 lore raw

v2 cover perf tools: Fix for cases where cpumode is incorrect or insufficient

Hi

Here is V2:
These patches probably deal with most cases except the one fixed by David Miller's "perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}" patch, and also cat_backtrace() which looks like it has the same problem, and the cs-etm fix.

Changes in V2:
perf tools: Add fallback functions for cases where cpumode is insufficient
Rename fallback functions to both end in _fb
Add and use variable machine->single_address_space

perf tools: Use fallback for sample_addr_correlates_sym() cases perf tools: Use fallbacks for branch stacks
Adjusted for the re-naming above

perf intel-pt: Insert callchain context into synthesized callchains perf intel-pt/bts: Calculate cpumode for synthesized samples
Dropped because they have been applied

Adrian Hunter (3):
perf tools: Add fallback functions for cases where cpumode is insufficient perf tools: Use fallback for sample_addr_correlates_sym() cases perf tools: Use fallbacks for branch stacks

 tools/perf/arch/common.c                           | 10 ++++++++
 tools/perf/arch/common.h                           |  1 +
 tools/perf/builtin-script.c                        | 12 ++++-----
 tools/perf/util/event.c                            | 29 +++++++++++++++++++++-
 tools/perf/util/machine.c                          | 27 ++++++++++++++++++++
 tools/perf/util/machine.h                          |  3 +++
 .../util/scripting-engines/trace-event-python.c    | 16 ++++++------
 tools/perf/util/session.c                          |  4 +++
 tools/perf/util/thread.h                           |  4 +++
 9 files changed, 91 insertions(+), 15 deletions(-)

Regards
Adrian

author reviewer
#1 lore raw

PATCH v2 1/3 perf tools: Add fallback functions for cases where cpumode is insufficient

For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases

---
 tools/perf/arch/common.c  | 10 ++++++++++
 tools/perf/arch/common.h  |  1 +
 tools/perf/util/event.c   | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.h |  3 +++
 tools/perf/util/session.c |  4 ++++
 tools/perf/util/thread.h  |  4 ++++
 7 files changed, 76 insertions(+)
tools/perf/arch/common.c +10 -0
index 82657c01a3b8..5f69fd0b745a 100644
@@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf_env *env, const char **path)
 
 	return perf_env__lookup_binutils_path(env, "objdump", path);
 }
+
+/*
+ * Some architectures have a single address space for kernel and user addresses,
+ * which makes it possible to determine if an address is in kernel space or user
+ * space.
+ */
+bool perf_env__single_address_space(struct perf_env *env)
+{
+	return strcmp(perf_env__arch(env), "sparc");
+}
tools/perf/arch/common.h +1 -0
index 2167001b18c5..c298a446d1f6 100644
@@ -5,5 +5,6 @@
 #include "../util/env.h"
 
 int perf_env__lookup_objdump(struct perf_env *env, const char **path);
+bool perf_env__single_address_space(struct perf_env *env);
 
 #endif /* ARCH_PERF_COMMON_H */
tools/perf/util/event.c +27 -0
index e9c108a6b1c3..9431b20c1337 100644
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 	return al->map;
 }
 
+/*
+ * For branch stacks or branch samples, the sample cpumode might not be correct
+ * because it applies only to the sample 'ip' and not necessary to 'addr' or
+ * branch stack addresses. If possible, use a fallback to deal with those cases.
+ */
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al)
+{
+	struct map *map = thread__find_map(thread, cpumode, addr, al);
+	struct machine *machine = thread->mg->machine;
+	u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
+
+	if (map || addr_cpumode == cpumode)
+		return map;
+
+	return thread__find_map(thread, addr_cpumode, addr, al);
+}
+
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al)
 {
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 	return al->sym;
 }
 
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al)
+{
+	al->sym = NULL;
+	if (thread__find_map_fb(thread, cpumode, addr, al))
+		al->sym = map__find_symbol(al->map, al->addr);
+	return al->sym;
+}
+
 /*
  * Callers need to drop the reference to al->thread, obtained in
  * machine__findnew_thread()
tools/perf/util/machine.c +27 -0
index 8f36ce813bc5..9397e3f2444d 100644
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)
 	return err;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
+{
+	u8 addr_cpumode = cpumode;
+	bool kernel_ip;
+
+	if (!machine->single_address_space)
+		goto out;
+
+	kernel_ip = machine__kernel_ip(machine, addr);
+	switch (cpumode) {
+	case PERF_RECORD_MISC_KERNEL:
+	case PERF_RECORD_MISC_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
+					   PERF_RECORD_MISC_USER;
+		break;
+	case PERF_RECORD_MISC_GUEST_KERNEL:
+	case PERF_RECORD_MISC_GUEST_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
+					   PERF_RECORD_MISC_GUEST_USER;
+		break;
+	default:
+		break;
+	}
+out:
+	return addr_cpumode;
+}
+
 struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
 {
 	return dsos__findnew(&machine->dsos, filename);
tools/perf/util/machine.h +3 -0
index d856b85862e2..ebde3ea70225 100644
@@ -42,6 +42,7 @@ struct machine {
 	u16		  id_hdr_size;
 	bool		  comm_exec;
 	bool		  kptr_restrict_warned;
+	bool		  single_address_space;
 	char		  *root_dir;
 	char		  *mmap_name;
 	struct threads    threads[THREADS__TABLE_SIZE];
@@ -99,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
 	return ip >= kernel_start;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
+
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 				    pid_t tid);
 struct comm *machine__thread_exec_comm(struct machine *machine,
tools/perf/util/session.c +4 -0
index 7d2c8ce6cfad..f8eab197f35c 100644
@@ -24,6 +24,7 @@
 #include "thread.h"
 #include "thread-stack.h"
 #include "stat.h"
+#include "arch/common.h"
 
 static int perf_session__deliver_event(struct perf_session *session,
 				       union perf_event *event,
@@ -150,6 +151,9 @@ struct perf_session *perf_session__new(struct perf_data *data,
 		session->machines.host.env = &perf_env;
 	}
 
+	session->machines.host.single_address_space =
+		perf_env__single_address_space(session->machines.host.env);
+
 	if (!data || perf_data__is_write(data)) {
 		/*
 		 * In O_RDONLY mode this will be performed when reading the
tools/perf/util/thread.h +4 -0
index 30e2b4c165fe..5920c3bb8ffe 100644
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
 
 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 			     struct addr_location *al);
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al);
 
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al);
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al);
 
 void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
 					struct addr_location *al);
Signature · 1 line
2.17.1
Acked-by on v2 1/3
#2 lore raw

Re: [PATCH V2 1/3] perf tools: Add fallback functions for cases where cpumode is insufficient

From: Adrian Hunter <[email protected]>
Date: Tue, 6 Nov 2018 23:07:10 +0200

Quoted 6 lines

For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases

#3 lore raw

Re: [PATCH V2 1/3] perf tools: Add fallback functions for cases where cpumode is insufficient

In reply to Adrian Hunter

Em Tue, Nov 06, 2018 at 11:07:10PM +0200, Adrian Hunter escreveu:

Quoted 4 lines

For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases

I've split this into two, and the first is causing this:

root@quaco ~]# perf top
perf: Segmentation fault
-------- backtrace --------
perf[0x59baca] /lib64/libc.so.6(+0x385bf)[0x7fa2775dc5bf] perf(perf_env__arch+0x34)[0x4b4514] perf(perf_env__single_address_space+0x1b)[0x57944b] perf(perf_session__new+0x17c)[0x4fdb3c] perf(cmd_top+0x162c)[0x45109c]
perf[0x4a621e]
perf(main+0x61c)[0x42cbfc] /lib64/libc.so.6(__libc_start_main+0xf2)[0x7fa2775c8412] perf(_start+0x2d)[0x42ce2d]
[root@quaco ~]#

Its the case where the env info comes from the running machine, via uname(), I'm working on a fix.

- Arnaldo

Quoted 187 lines
---
 tools/perf/arch/common.c  | 10 ++++++++++
 tools/perf/arch/common.h  |  1 +
 tools/perf/util/event.c   | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.h |  3 +++
 tools/perf/util/session.c |  4 ++++
 tools/perf/util/thread.h  |  4 ++++
 7 files changed, 76 insertions(+)
tools/perf/arch/common.c +10 -0
index 82657c01a3b8..5f69fd0b745a 100644
@@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf_env *env, const char **path)
 
 	return perf_env__lookup_binutils_path(env, "objdump", path);
 }
+
+/*
+ * Some architectures have a single address space for kernel and user addresses,
+ * which makes it possible to determine if an address is in kernel space or user
+ * space.
+ */
+bool perf_env__single_address_space(struct perf_env *env)
+{
+	return strcmp(perf_env__arch(env), "sparc");
+}
tools/perf/arch/common.h +1 -0
index 2167001b18c5..c298a446d1f6 100644
@@ -5,5 +5,6 @@
 #include "../util/env.h"
 
 int perf_env__lookup_objdump(struct perf_env *env, const char **path);
+bool perf_env__single_address_space(struct perf_env *env);
 
 #endif /* ARCH_PERF_COMMON_H */
tools/perf/util/event.c +27 -0
index e9c108a6b1c3..9431b20c1337 100644
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 	return al->map;
 }
 
+/*
+ * For branch stacks or branch samples, the sample cpumode might not be correct
+ * because it applies only to the sample 'ip' and not necessary to 'addr' or
+ * branch stack addresses. If possible, use a fallback to deal with those cases.
+ */
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al)
+{
+	struct map *map = thread__find_map(thread, cpumode, addr, al);
+	struct machine *machine = thread->mg->machine;
+	u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
+
+	if (map || addr_cpumode == cpumode)
+		return map;
+
+	return thread__find_map(thread, addr_cpumode, addr, al);
+}
+
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al)
 {
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 	return al->sym;
 }
 
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al)
+{
+	al->sym = NULL;
+	if (thread__find_map_fb(thread, cpumode, addr, al))
+		al->sym = map__find_symbol(al->map, al->addr);
+	return al->sym;
+}
+
 /*
  * Callers need to drop the reference to al->thread, obtained in
  * machine__findnew_thread()
tools/perf/util/machine.c +27 -0
index 8f36ce813bc5..9397e3f2444d 100644
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)
 	return err;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
+{
+	u8 addr_cpumode = cpumode;
+	bool kernel_ip;
+
+	if (!machine->single_address_space)
+		goto out;
+
+	kernel_ip = machine__kernel_ip(machine, addr);
+	switch (cpumode) {
+	case PERF_RECORD_MISC_KERNEL:
+	case PERF_RECORD_MISC_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
+					   PERF_RECORD_MISC_USER;
+		break;
+	case PERF_RECORD_MISC_GUEST_KERNEL:
+	case PERF_RECORD_MISC_GUEST_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
+					   PERF_RECORD_MISC_GUEST_USER;
+		break;
+	default:
+		break;
+	}
+out:
+	return addr_cpumode;
+}
+
 struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
 {
 	return dsos__findnew(&machine->dsos, filename);
tools/perf/util/machine.h +3 -0
index d856b85862e2..ebde3ea70225 100644
@@ -42,6 +42,7 @@ struct machine {
 	u16		  id_hdr_size;
 	bool		  comm_exec;
 	bool		  kptr_restrict_warned;
+	bool		  single_address_space;
 	char		  *root_dir;
 	char		  *mmap_name;
 	struct threads    threads[THREADS__TABLE_SIZE];
@@ -99,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
 	return ip >= kernel_start;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
+
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 				    pid_t tid);
 struct comm *machine__thread_exec_comm(struct machine *machine,
tools/perf/util/session.c +4 -0
index 7d2c8ce6cfad..f8eab197f35c 100644
@@ -24,6 +24,7 @@
 #include "thread.h"
 #include "thread-stack.h"
 #include "stat.h"
+#include "arch/common.h"
 
 static int perf_session__deliver_event(struct perf_session *session,
 				       union perf_event *event,
@@ -150,6 +151,9 @@ struct perf_session *perf_session__new(struct perf_data *data,
 		session->machines.host.env = &perf_env;
 	}
 
+	session->machines.host.single_address_space =
+		perf_env__single_address_space(session->machines.host.env);
+
 	if (!data || perf_data__is_write(data)) {
 		/*
 		 * In O_RDONLY mode this will be performed when reading the
tools/perf/util/thread.h +4 -0
index 30e2b4c165fe..5920c3bb8ffe 100644
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
 
 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 			     struct addr_location *al);
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al);
 
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al);
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al);
 
 void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
 					struct addr_location *al);
Signature · 1 line
2.17.1
Signature · 1 line
- Arnaldo
#4 lore raw

Re: [PATCH V2 1/3] perf tools: Add fallback functions for cases where cpumode is insufficient

Em Tue, Nov 27, 2018 at 11:10:36AM -0300, Arnaldo Carvalho de Melo escreveu:

Quoted 23 lines

Em Tue, Nov 06, 2018 at 11:07:10PM +0200, Adrian Hunter escreveu:

Quoted 4 lines

For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases

I've split this into two, and the first is causing this:

root@quaco ~]# perf top
perf: Segmentation fault
-------- backtrace --------
perf[0x59baca] /lib64/libc.so.6(+0x385bf)[0x7fa2775dc5bf] perf(perf_env__arch+0x34)[0x4b4514] perf(perf_env__single_address_space+0x1b)[0x57944b] perf(perf_session__new+0x17c)[0x4fdb3c] perf(cmd_top+0x162c)[0x45109c]
perf[0x4a621e]
perf(main+0x61c)[0x42cbfc] /lib64/libc.so.6(__libc_start_main+0xf2)[0x7fa2775c8412] perf(_start+0x2d)[0x42ce2d]
[root@quaco ~]#

Quoted 2 lines

Its the case where the env info comes from the running machine, via uname(), I'm working on a fix.

So I'll graft this just before your patch.

- Arnaldo

tools/perf/util/env.c +1 -1
index 59f38c7693f8..4c23779e271a 100644
@@ -166,7 +166,7 @@ const char *perf_env__arch(struct perf_env *env)
 	struct utsname uts;
 	char *arch_name;
 
-	if (!env) { /* Assume local operation */
+	if (!env || !env->arch) { /* Assume local operation */
 		if (uname(&uts) < 0)
 			return NULL;
 		arch_name = uts.machine;
#5 lore raw

[tip:perf/core] perf thread: Add fallback functions for cases where cpumode is insufficient

In reply to Adrian Hunter
perf thread: Add fallback functions for cases where cpumode is insufficient
Commit-ID:  23abfb26071009e022355c3bcba6502cd7b4dc61
Gitweb:     https://git.kernel.org/tip/23abfb26071009e022355c3bcba6502cd7b4dc61
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:10 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Thu, 29 Nov 2018 20:42:47 -0300

perf thread: Add fallback functions for cases where cpumode is insufficient

For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases

---
 tools/perf/util/event.c   | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.h |  2 ++
 tools/perf/util/thread.h  |  4 ++++
 4 files changed, 60 insertions(+)
tools/perf/util/event.c +27 -0
index e9c108a6b1c3..9431b20c1337 100644
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 	return al->map;
 }
 
+/*
+ * For branch stacks or branch samples, the sample cpumode might not be correct
+ * because it applies only to the sample 'ip' and not necessary to 'addr' or
+ * branch stack addresses. If possible, use a fallback to deal with those cases.
+ */
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al)
+{
+	struct map *map = thread__find_map(thread, cpumode, addr, al);
+	struct machine *machine = thread->mg->machine;
+	u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
+
+	if (map || addr_cpumode == cpumode)
+		return map;
+
+	return thread__find_map(thread, addr_cpumode, addr, al);
+}
+
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al)
 {
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 	return al->sym;
 }
 
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al)
+{
+	al->sym = NULL;
+	if (thread__find_map_fb(thread, cpumode, addr, al))
+		al->sym = map__find_symbol(al->map, al->addr);
+	return al->sym;
+}
+
 /*
  * Callers need to drop the reference to al->thread, obtained in
  * machine__findnew_thread()
tools/perf/util/machine.c +27 -0
index 8f36ce813bc5..9397e3f2444d 100644
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)
 	return err;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
+{
+	u8 addr_cpumode = cpumode;
+	bool kernel_ip;
+
+	if (!machine->single_address_space)
+		goto out;
+
+	kernel_ip = machine__kernel_ip(machine, addr);
+	switch (cpumode) {
+	case PERF_RECORD_MISC_KERNEL:
+	case PERF_RECORD_MISC_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
+					   PERF_RECORD_MISC_USER;
+		break;
+	case PERF_RECORD_MISC_GUEST_KERNEL:
+	case PERF_RECORD_MISC_GUEST_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
+					   PERF_RECORD_MISC_GUEST_USER;
+		break;
+	default:
+		break;
+	}
+out:
+	return addr_cpumode;
+}
+
 struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
 {
 	return dsos__findnew(&machine->dsos, filename);
tools/perf/util/machine.h +2 -0
index ca897a73014c..ebde3ea70225 100644
@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
 	return ip >= kernel_start;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
+
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 				    pid_t tid);
 struct comm *machine__thread_exec_comm(struct machine *machine,
tools/perf/util/thread.h +4 -0
index 30e2b4c165fe..5920c3bb8ffe 100644
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
 
 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 			     struct addr_location *al);
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al);
 
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al);
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al);
 
 void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
 					struct addr_location *al);
#6 lore raw

[tip:perf/core] perf machine: Record if a arch has a single user/kernel address space

In reply to Adrian Hunter
perf machine: Record if a arch has a single user/kernel address space
Commit-ID:  cc9581b785fd3f2e64d44641a94179d18ffdbe34
Gitweb:     https://git.kernel.org/tip/cc9581b785fd3f2e64d44641a94179d18ffdbe34
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:10 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Thu, 29 Nov 2018 20:42:47 -0300

perf machine: Record if a arch has a single user/kernel address space

Some architectures have a single address space for kernel and user addresses, which makes it possible to determine if an address is in kernel space or user space. Some don't, e.g.: sparc.

Cache that info in perf_env so that, for instance, code needing to fallback failed symbol lookups at the kernel space in single address space arches can lookup at userspace.

---
 tools/perf/arch/common.c  | 10 ++++++++++
 tools/perf/arch/common.h  |  1 +
 tools/perf/util/machine.h |  1 +
 tools/perf/util/session.c |  4 ++++
 4 files changed, 16 insertions(+)
tools/perf/arch/common.c +10 -0
index 82657c01a3b8..5f69fd0b745a 100644
@@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf_env *env, const char **path)
 
 	return perf_env__lookup_binutils_path(env, "objdump", path);
 }
+
+/*
+ * Some architectures have a single address space for kernel and user addresses,
+ * which makes it possible to determine if an address is in kernel space or user
+ * space.
+ */
+bool perf_env__single_address_space(struct perf_env *env)
+{
+	return strcmp(perf_env__arch(env), "sparc");
+}
tools/perf/arch/common.h +1 -0
index 2167001b18c5..c298a446d1f6 100644
@@ -5,5 +5,6 @@
 #include "../util/env.h"
 
 int perf_env__lookup_objdump(struct perf_env *env, const char **path);
+bool perf_env__single_address_space(struct perf_env *env);
 
 #endif /* ARCH_PERF_COMMON_H */
tools/perf/util/machine.h +1 -0
index d856b85862e2..ca897a73014c 100644
@@ -42,6 +42,7 @@ struct machine {
 	u16		  id_hdr_size;
 	bool		  comm_exec;
 	bool		  kptr_restrict_warned;
+	bool		  single_address_space;
 	char		  *root_dir;
 	char		  *mmap_name;
 	struct threads    threads[THREADS__TABLE_SIZE];
tools/perf/util/session.c +4 -0
index 7d2c8ce6cfad..f8eab197f35c 100644
@@ -24,6 +24,7 @@
 #include "thread.h"
 #include "thread-stack.h"
 #include "stat.h"
+#include "arch/common.h"
 
 static int perf_session__deliver_event(struct perf_session *session,
 				       union perf_event *event,
@@ -150,6 +151,9 @@ struct perf_session *perf_session__new(struct perf_data *data,
 		session->machines.host.env = &perf_env;
 	}
 
+	session->machines.host.single_address_space =
+		perf_env__single_address_space(session->machines.host.env);
+
 	if (!data || perf_data__is_write(data)) {
 		/*
 		 * In O_RDONLY mode this will be performed when reading the
#7 lore raw

[tip:perf/core] perf machine: Record if a arch has a single user/kernel address space

In reply to Adrian Hunter
perf machine: Record if a arch has a single user/kernel address space
Commit-ID:  ec1891afae740be581ecf5abc8bda74c4549203f
Gitweb:     https://git.kernel.org/tip/ec1891afae740be581ecf5abc8bda74c4549203f
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:10 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 17 Dec 2018 14:54:07 -0300

perf machine: Record if a arch has a single user/kernel address space

Some architectures have a single address space for kernel and user addresses, which makes it possible to determine if an address is in kernel space or user space. Some don't, e.g.: sparc.

Cache that info in perf_env so that, for instance, code needing to fallback failed symbol lookups at the kernel space in single address space arches can lookup at userspace.

---
 tools/perf/arch/common.c  | 10 ++++++++++
 tools/perf/arch/common.h  |  1 +
 tools/perf/util/machine.h |  1 +
 tools/perf/util/session.c |  4 ++++
 4 files changed, 16 insertions(+)
tools/perf/arch/common.c +10 -0
index 82657c01a3b8..5f69fd0b745a 100644
@@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf_env *env, const char **path)
 
 	return perf_env__lookup_binutils_path(env, "objdump", path);
 }
+
+/*
+ * Some architectures have a single address space for kernel and user addresses,
+ * which makes it possible to determine if an address is in kernel space or user
+ * space.
+ */
+bool perf_env__single_address_space(struct perf_env *env)
+{
+	return strcmp(perf_env__arch(env), "sparc");
+}
tools/perf/arch/common.h +1 -0
index 2167001b18c5..c298a446d1f6 100644
@@ -5,5 +5,6 @@
 #include "../util/env.h"
 
 int perf_env__lookup_objdump(struct perf_env *env, const char **path);
+bool perf_env__single_address_space(struct perf_env *env);
 
 #endif /* ARCH_PERF_COMMON_H */
tools/perf/util/machine.h +1 -0
index d856b85862e2..ca897a73014c 100644
@@ -42,6 +42,7 @@ struct machine {
 	u16		  id_hdr_size;
 	bool		  comm_exec;
 	bool		  kptr_restrict_warned;
+	bool		  single_address_space;
 	char		  *root_dir;
 	char		  *mmap_name;
 	struct threads    threads[THREADS__TABLE_SIZE];
tools/perf/util/session.c +4 -0
index 7d2c8ce6cfad..f8eab197f35c 100644
@@ -24,6 +24,7 @@
 #include "thread.h"
 #include "thread-stack.h"
 #include "stat.h"
+#include "arch/common.h"
 
 static int perf_session__deliver_event(struct perf_session *session,
 				       union perf_event *event,
@@ -150,6 +151,9 @@ struct perf_session *perf_session__new(struct perf_data *data,
 		session->machines.host.env = &perf_env;
 	}
 
+	session->machines.host.single_address_space =
+		perf_env__single_address_space(session->machines.host.env);
+
 	if (!data || perf_data__is_write(data)) {
 		/*
 		 * In O_RDONLY mode this will be performed when reading the
#8 lore raw

[tip:perf/core] perf thread: Add fallback functions for cases where cpumode is insufficient

In reply to Adrian Hunter
perf thread: Add fallback functions for cases where cpumode is insufficient
Commit-ID:  8e80ad9983caeee09c3a0a1a37e05bff93becce4
Gitweb:     https://git.kernel.org/tip/8e80ad9983caeee09c3a0a1a37e05bff93becce4
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:10 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 17 Dec 2018 14:54:13 -0300

perf thread: Add fallback functions for cases where cpumode is insufficient

For branch stacks or branch samples, the sample cpumode might not be correct because it applies only to the sample 'ip' and not necessary to 'addr' or branch stack addresses. Add fallback functions that can be used to deal with those cases

---
 tools/perf/util/event.c   | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++
 tools/perf/util/machine.h |  2 ++
 tools/perf/util/thread.h  |  4 ++++
 4 files changed, 60 insertions(+)
tools/perf/util/event.c +27 -0
index e9c108a6b1c3..9431b20c1337 100644
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 	return al->map;
 }
 
+/*
+ * For branch stacks or branch samples, the sample cpumode might not be correct
+ * because it applies only to the sample 'ip' and not necessary to 'addr' or
+ * branch stack addresses. If possible, use a fallback to deal with those cases.
+ */
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al)
+{
+	struct map *map = thread__find_map(thread, cpumode, addr, al);
+	struct machine *machine = thread->mg->machine;
+	u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
+
+	if (map || addr_cpumode == cpumode)
+		return map;
+
+	return thread__find_map(thread, addr_cpumode, addr, al);
+}
+
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al)
 {
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 	return al->sym;
 }
 
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al)
+{
+	al->sym = NULL;
+	if (thread__find_map_fb(thread, cpumode, addr, al))
+		al->sym = map__find_symbol(al->map, al->addr);
+	return al->sym;
+}
+
 /*
  * Callers need to drop the reference to al->thread, obtained in
  * machine__findnew_thread()
tools/perf/util/machine.c +27 -0
index 8f36ce813bc5..9397e3f2444d 100644
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)
 	return err;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
+{
+	u8 addr_cpumode = cpumode;
+	bool kernel_ip;
+
+	if (!machine->single_address_space)
+		goto out;
+
+	kernel_ip = machine__kernel_ip(machine, addr);
+	switch (cpumode) {
+	case PERF_RECORD_MISC_KERNEL:
+	case PERF_RECORD_MISC_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
+					   PERF_RECORD_MISC_USER;
+		break;
+	case PERF_RECORD_MISC_GUEST_KERNEL:
+	case PERF_RECORD_MISC_GUEST_USER:
+		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
+					   PERF_RECORD_MISC_GUEST_USER;
+		break;
+	default:
+		break;
+	}
+out:
+	return addr_cpumode;
+}
+
 struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
 {
 	return dsos__findnew(&machine->dsos, filename);
tools/perf/util/machine.h +2 -0
index ca897a73014c..ebde3ea70225 100644
@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
 	return ip >= kernel_start;
 }
 
+u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
+
 struct thread *machine__find_thread(struct machine *machine, pid_t pid,
 				    pid_t tid);
 struct comm *machine__thread_exec_comm(struct machine *machine,
tools/perf/util/thread.h +4 -0
index 30e2b4c165fe..5920c3bb8ffe 100644
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
 
 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 			     struct addr_location *al);
+struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
+				struct addr_location *al);
 
 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
 				   u64 addr, struct addr_location *al);
+struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
+				      u64 addr, struct addr_location *al);
 
 void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
 					struct addr_location *al);
author reviewer
#9 lore raw

PATCH v2 2/3 perf tools: Use fallback for sample_addr_correlates_sym() cases

In reply to Adrian Hunter

thread__resolve() is used in the sample_addr_correlates_sym() cases where 'addr' is a destination of a branch which does not necessarily have the same cpumode as the 'ip'. Use the fallback function in that case.

This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".

---
 tools/perf/util/event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/event.c +1 -1
index 9431b20c1337..24493200cf80 100644
@@ -1706,7 +1706,7 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
 void thread__resolve(struct thread *thread, struct addr_location *al,
 		     struct perf_sample *sample)
 {
-	thread__find_map(thread, sample->cpumode, sample->addr, al);
+	thread__find_map_fb(thread, sample->cpumode, sample->addr, al);
 
 	al->cpu = sample->cpu;
 	al->sym = NULL;
Signature · 1 line
2.17.1
#10 lore raw

[tip:perf/core] perf tools: Use fallback for sample_addr_correlates_sym() cases

perf tools: Use fallback for sample_addr_correlates_sym() cases
Commit-ID:  cbf7c5b09202693cfc17ac87d7ad45f622ab4937
Gitweb:     https://git.kernel.org/tip/cbf7c5b09202693cfc17ac87d7ad45f622ab4937
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:11 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Thu, 29 Nov 2018 20:42:47 -0300

perf tools: Use fallback for sample_addr_correlates_sym() cases

thread__resolve() is used in the sample_addr_correlates_sym() cases where 'addr' is a destination of a branch which does not necessarily have the same cpumode as the 'ip'. Use the fallback function in that case.

This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".

---
 tools/perf/util/event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/event.c +1 -1
index 9431b20c1337..24493200cf80 100644
@@ -1706,7 +1706,7 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
 void thread__resolve(struct thread *thread, struct addr_location *al,
 		     struct perf_sample *sample)
 {
-	thread__find_map(thread, sample->cpumode, sample->addr, al);
+	thread__find_map_fb(thread, sample->cpumode, sample->addr, al);
 
 	al->cpu = sample->cpu;
 	al->sym = NULL;
#11 lore raw

[tip:perf/core] perf tools: Use fallback for sample_addr_correlates_sym() cases

In reply to Adrian Hunter
perf tools: Use fallback for sample_addr_correlates_sym() cases
Commit-ID:  225f99e0c811e23836c4911a2ff147e167dd1fe8
Gitweb:     https://git.kernel.org/tip/225f99e0c811e23836c4911a2ff147e167dd1fe8
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:11 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 17 Dec 2018 14:54:16 -0300

perf tools: Use fallback for sample_addr_correlates_sym() cases

thread__resolve() is used in the sample_addr_correlates_sym() cases where 'addr' is a destination of a branch which does not necessarily have the same cpumode as the 'ip'. Use the fallback function in that case.

This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".

---
 tools/perf/util/event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/event.c +1 -1
index 9431b20c1337..24493200cf80 100644
@@ -1706,7 +1706,7 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
 void thread__resolve(struct thread *thread, struct addr_location *al,
 		     struct perf_sample *sample)
 {
-	thread__find_map(thread, sample->cpumode, sample->addr, al);
+	thread__find_map_fb(thread, sample->cpumode, sample->addr, al);
 
 	al->cpu = sample->cpu;
 	al->sym = NULL;
author reviewer
#12 lore raw

PATCH v2 3/3 perf tools: Use fallbacks for branch stacks

In reply to Adrian Hunter

Branch stacks do not necessarily have the same cpumode as the 'ip'. Use the fallback functions in those cases.

This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".

---
 tools/perf/builtin-script.c                      | 12 ++++++------
 .../util/scripting-engines/trace-event-python.c  | 16 ++++++++--------
 2 files changed, 14 insertions(+), 14 deletions(-)
tools/perf/builtin-script.c +6 -6
index b5bc85bd0bbe..a7b4d3f611c5 100644
@@ -728,8 +728,8 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,
 		if (PRINT_FIELD(DSO)) {
 			memset(&alf, 0, sizeof(alf));
 			memset(&alt, 0, sizeof(alt));
-			thread__find_map(thread, sample->cpumode, from, &alf);
-			thread__find_map(thread, sample->cpumode, to, &alt);
+			thread__find_map_fb(thread, sample->cpumode, from, &alf);
+			thread__find_map_fb(thread, sample->cpumode, to, &alt);
 		}
 
 		printed += fprintf(fp, " 0x%"PRIx64, from);
@@ -775,8 +775,8 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
 		from = br->entries[i].from;
 		to   = br->entries[i].to;
 
-		thread__find_symbol(thread, sample->cpumode, from, &alf);
-		thread__find_symbol(thread, sample->cpumode, to, &alt);
+		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
+		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
 
 		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
 		if (PRINT_FIELD(DSO)) {
@@ -820,11 +820,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
 		from = br->entries[i].from;
 		to   = br->entries[i].to;
 
-		if (thread__find_map(thread, sample->cpumode, from, &alf) &&
+		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
 		    !alf.map->dso->adjust_symbols)
 			from = map__map_ip(alf.map, from);
 
-		if (thread__find_map(thread, sample->cpumode, to, &alt) &&
+		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
 		    !alt.map->dso->adjust_symbols)
 			to = map__map_ip(alt.map, to);
 
tools/perf/util/scripting-engines/trace-event-python.c +8 -8
index 69aa93d4ee99..0c4b050f6fc2 100644
@@ -494,14 +494,14 @@ static PyObject *python_process_brstack(struct perf_sample *sample,
 		pydict_set_item_string_decref(pyelem, "cycles",
 		    PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles));
 
-		thread__find_map(thread, sample->cpumode,
-				 br->entries[i].from, &al);
+		thread__find_map_fb(thread, sample->cpumode,
+				    br->entries[i].from, &al);
 		dsoname = get_dsoname(al.map);
 		pydict_set_item_string_decref(pyelem, "from_dsoname",
 					      _PyUnicode_FromString(dsoname));
 
-		thread__find_map(thread, sample->cpumode,
-				 br->entries[i].to, &al);
+		thread__find_map_fb(thread, sample->cpumode,
+				    br->entries[i].to, &al);
 		dsoname = get_dsoname(al.map);
 		pydict_set_item_string_decref(pyelem, "to_dsoname",
 					      _PyUnicode_FromString(dsoname));
@@ -576,14 +576,14 @@ static PyObject *python_process_brstacksym(struct perf_sample *sample,
 		if (!pyelem)
 			Py_FatalError("couldn't create Python dictionary");
 
-		thread__find_symbol(thread, sample->cpumode,
-				    br->entries[i].from, &al);
+		thread__find_symbol_fb(thread, sample->cpumode,
+				       br->entries[i].from, &al);
 		get_symoff(al.sym, &al, true, bf, sizeof(bf));
 		pydict_set_item_string_decref(pyelem, "from",
 					      _PyUnicode_FromString(bf));
 
-		thread__find_symbol(thread, sample->cpumode,
-				    br->entries[i].to, &al);
+		thread__find_symbol_fb(thread, sample->cpumode,
+				       br->entries[i].to, &al);
 		get_symoff(al.sym, &al, true, bf, sizeof(bf));
 		pydict_set_item_string_decref(pyelem, "to",
 					      _PyUnicode_FromString(bf));
Signature · 1 line
2.17.1
#13 lore raw

[tip:perf/core] perf script: Use fallbacks for branch stacks

perf script: Use fallbacks for branch stacks
Commit-ID:  4ea9a7a364b6311b98c4a4e8e3692cdc253015dc
Gitweb:     https://git.kernel.org/tip/4ea9a7a364b6311b98c4a4e8e3692cdc253015dc
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:12 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Thu, 29 Nov 2018 20:42:47 -0300

perf script: Use fallbacks for branch stacks

Branch stacks do not necessarily have the same cpumode as the 'ip'. Use the fallback functions in those cases.

This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".

---
 tools/perf/builtin-script.c                            | 12 ++++++------
 tools/perf/util/scripting-engines/trace-event-python.c | 16 ++++++++--------
 2 files changed, 14 insertions(+), 14 deletions(-)
tools/perf/builtin-script.c +6 -6
index 04913136bac9..3ea98fe72f7f 100644
@@ -724,8 +724,8 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,
 		if (PRINT_FIELD(DSO)) {
 			memset(&alf, 0, sizeof(alf));
 			memset(&alt, 0, sizeof(alt));
-			thread__find_map(thread, sample->cpumode, from, &alf);
-			thread__find_map(thread, sample->cpumode, to, &alt);
+			thread__find_map_fb(thread, sample->cpumode, from, &alf);
+			thread__find_map_fb(thread, sample->cpumode, to, &alt);
 		}
 
 		printed += fprintf(fp, " 0x%"PRIx64, from);
@@ -771,8 +771,8 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
 		from = br->entries[i].from;
 		to   = br->entries[i].to;
 
-		thread__find_symbol(thread, sample->cpumode, from, &alf);
-		thread__find_symbol(thread, sample->cpumode, to, &alt);
+		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
+		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
 
 		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
 		if (PRINT_FIELD(DSO)) {
@@ -816,11 +816,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
 		from = br->entries[i].from;
 		to   = br->entries[i].to;
 
-		if (thread__find_map(thread, sample->cpumode, from, &alf) &&
+		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
 		    !alf.map->dso->adjust_symbols)
 			from = map__map_ip(alf.map, from);
 
-		if (thread__find_map(thread, sample->cpumode, to, &alt) &&
+		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
 		    !alt.map->dso->adjust_symbols)
 			to = map__map_ip(alt.map, to);
 
tools/perf/util/scripting-engines/trace-event-python.c +8 -8
index 69aa93d4ee99..0c4b050f6fc2 100644
@@ -494,14 +494,14 @@ static PyObject *python_process_brstack(struct perf_sample *sample,
 		pydict_set_item_string_decref(pyelem, "cycles",
 		    PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles));
 
-		thread__find_map(thread, sample->cpumode,
-				 br->entries[i].from, &al);
+		thread__find_map_fb(thread, sample->cpumode,
+				    br->entries[i].from, &al);
 		dsoname = get_dsoname(al.map);
 		pydict_set_item_string_decref(pyelem, "from_dsoname",
 					      _PyUnicode_FromString(dsoname));
 
-		thread__find_map(thread, sample->cpumode,
-				 br->entries[i].to, &al);
+		thread__find_map_fb(thread, sample->cpumode,
+				    br->entries[i].to, &al);
 		dsoname = get_dsoname(al.map);
 		pydict_set_item_string_decref(pyelem, "to_dsoname",
 					      _PyUnicode_FromString(dsoname));
@@ -576,14 +576,14 @@ static PyObject *python_process_brstacksym(struct perf_sample *sample,
 		if (!pyelem)
 			Py_FatalError("couldn't create Python dictionary");
 
-		thread__find_symbol(thread, sample->cpumode,
-				    br->entries[i].from, &al);
+		thread__find_symbol_fb(thread, sample->cpumode,
+				       br->entries[i].from, &al);
 		get_symoff(al.sym, &al, true, bf, sizeof(bf));
 		pydict_set_item_string_decref(pyelem, "from",
 					      _PyUnicode_FromString(bf));
 
-		thread__find_symbol(thread, sample->cpumode,
-				    br->entries[i].to, &al);
+		thread__find_symbol_fb(thread, sample->cpumode,
+				       br->entries[i].to, &al);
 		get_symoff(al.sym, &al, true, bf, sizeof(bf));
 		pydict_set_item_string_decref(pyelem, "to",
 					      _PyUnicode_FromString(bf));
#14 lore raw

[tip:perf/core] perf script: Use fallbacks for branch stacks

In reply to Adrian Hunter
perf script: Use fallbacks for branch stacks
Commit-ID:  692d0e63324d2954a0c63a812a8588e97023a295
Gitweb:     https://git.kernel.org/tip/692d0e63324d2954a0c63a812a8588e97023a295
Author:     Adrian Hunter <[email protected]>
AuthorDate: Tue, 6 Nov 2018 23:07:12 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 17 Dec 2018 14:54:18 -0300

perf script: Use fallbacks for branch stacks

Branch stacks do not necessarily have the same cpumode as the 'ip'. Use the fallback functions in those cases.

This patch depends on patch "perf tools: Add fallback functions for cases where cpumode is insufficient".

---
 tools/perf/builtin-script.c                            | 12 ++++++------
 tools/perf/util/scripting-engines/trace-event-python.c | 16 ++++++++--------
 2 files changed, 14 insertions(+), 14 deletions(-)
tools/perf/builtin-script.c +6 -6
index 04913136bac9..3ea98fe72f7f 100644
@@ -724,8 +724,8 @@ static int perf_sample__fprintf_brstack(struct perf_sample *sample,
 		if (PRINT_FIELD(DSO)) {
 			memset(&alf, 0, sizeof(alf));
 			memset(&alt, 0, sizeof(alt));
-			thread__find_map(thread, sample->cpumode, from, &alf);
-			thread__find_map(thread, sample->cpumode, to, &alt);
+			thread__find_map_fb(thread, sample->cpumode, from, &alf);
+			thread__find_map_fb(thread, sample->cpumode, to, &alt);
 		}
 
 		printed += fprintf(fp, " 0x%"PRIx64, from);
@@ -771,8 +771,8 @@ static int perf_sample__fprintf_brstacksym(struct perf_sample *sample,
 		from = br->entries[i].from;
 		to   = br->entries[i].to;
 
-		thread__find_symbol(thread, sample->cpumode, from, &alf);
-		thread__find_symbol(thread, sample->cpumode, to, &alt);
+		thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
+		thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
 
 		printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
 		if (PRINT_FIELD(DSO)) {
@@ -816,11 +816,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
 		from = br->entries[i].from;
 		to   = br->entries[i].to;
 
-		if (thread__find_map(thread, sample->cpumode, from, &alf) &&
+		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
 		    !alf.map->dso->adjust_symbols)
 			from = map__map_ip(alf.map, from);
 
-		if (thread__find_map(thread, sample->cpumode, to, &alt) &&
+		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
 		    !alt.map->dso->adjust_symbols)
 			to = map__map_ip(alt.map, to);
 
tools/perf/util/scripting-engines/trace-event-python.c +8 -8
index 69aa93d4ee99..0c4b050f6fc2 100644
@@ -494,14 +494,14 @@ static PyObject *python_process_brstack(struct perf_sample *sample,
 		pydict_set_item_string_decref(pyelem, "cycles",
 		    PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles));
 
-		thread__find_map(thread, sample->cpumode,
-				 br->entries[i].from, &al);
+		thread__find_map_fb(thread, sample->cpumode,
+				    br->entries[i].from, &al);
 		dsoname = get_dsoname(al.map);
 		pydict_set_item_string_decref(pyelem, "from_dsoname",
 					      _PyUnicode_FromString(dsoname));
 
-		thread__find_map(thread, sample->cpumode,
-				 br->entries[i].to, &al);
+		thread__find_map_fb(thread, sample->cpumode,
+				    br->entries[i].to, &al);
 		dsoname = get_dsoname(al.map);
 		pydict_set_item_string_decref(pyelem, "to_dsoname",
 					      _PyUnicode_FromString(dsoname));
@@ -576,14 +576,14 @@ static PyObject *python_process_brstacksym(struct perf_sample *sample,
 		if (!pyelem)
 			Py_FatalError("couldn't create Python dictionary");
 
-		thread__find_symbol(thread, sample->cpumode,
-				    br->entries[i].from, &al);
+		thread__find_symbol_fb(thread, sample->cpumode,
+				       br->entries[i].from, &al);
 		get_symoff(al.sym, &al, true, bf, sizeof(bf));
 		pydict_set_item_string_decref(pyelem, "from",
 					      _PyUnicode_FromString(bf));
 
-		thread__find_symbol(thread, sample->cpumode,
-				    br->entries[i].to, &al);
+		thread__find_symbol_fb(thread, sample->cpumode,
+				       br->entries[i].to, &al);
 		get_symoff(al.sym, &al, true, bf, sizeof(bf));
 		pydict_set_item_string_decref(pyelem, "to",
 					      _PyUnicode_FromString(bf));
author reviewer
#15 lore raw
In reply to Adrian Hunter
Quoted 5 lines · Adrian Hunter

Here is V2:
These patches probably deal with most cases except the one fixed by David Miller's "perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}" patch, and also cat_backtrace() which looks like it has the same problem, and the cs-etm fix.

Are these patches ok?

#16 lore raw

Em Mon, Nov 19, 2018 at 03:37:37PM +0200, Adrian Hunter escreveu:

Quoted 8 lines · Adrian Hunter
Quoted 5 lines

Here is V2:
These patches probably deal with most cases except the one fixed by David Miller's "perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}" patch, and also cat_backtrace() which looks like it has the same problem, and the cs-etm fix.

Are these patches ok?

Just got back from LPC, will resume reviewing these soon.

- Arnaldo