diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-03-11 15:16:49 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-03-14 17:08:40 -0400 |
commit | 52a3cb8cfca16db73cf825cb94325cf54da8304f (patch) | |
tree | e926190fca91c320768087d428b16bc2078784d1 /tools | |
parent | 0ea590ae8198547d5898c72b04fa9d8f23bd0b8f (diff) |
perf symbols: Introduce thread__find_cpumode_addr_location
Its one level up thread__find_addr_location, where it will look in
different domains for a sample: user, kernel, hypervisor, etc.
Will soon be used by a patchkit by Andi Kleen.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-so6nxkh7xj48bc5kq4jpj991@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/machine.c | 33 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 21 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 5 |
3 files changed, 34 insertions, 25 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 813e94e7cf29..a6799538069c 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1184,39 +1184,22 @@ static bool symbol__match_regex(struct symbol *sym, regex_t *regex) | |||
1184 | return 0; | 1184 | return 0; |
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | static const u8 cpumodes[] = { | ||
1188 | PERF_RECORD_MISC_USER, | ||
1189 | PERF_RECORD_MISC_KERNEL, | ||
1190 | PERF_RECORD_MISC_GUEST_USER, | ||
1191 | PERF_RECORD_MISC_GUEST_KERNEL | ||
1192 | }; | ||
1193 | #define NCPUMODES (sizeof(cpumodes)/sizeof(u8)) | ||
1194 | |||
1195 | static void ip__resolve_ams(struct machine *machine, struct thread *thread, | 1187 | static void ip__resolve_ams(struct machine *machine, struct thread *thread, |
1196 | struct addr_map_symbol *ams, | 1188 | struct addr_map_symbol *ams, |
1197 | u64 ip) | 1189 | u64 ip) |
1198 | { | 1190 | { |
1199 | struct addr_location al; | 1191 | struct addr_location al; |
1200 | size_t i; | ||
1201 | u8 m; | ||
1202 | 1192 | ||
1203 | memset(&al, 0, sizeof(al)); | 1193 | memset(&al, 0, sizeof(al)); |
1194 | /* | ||
1195 | * We cannot use the header.misc hint to determine whether a | ||
1196 | * branch stack address is user, kernel, guest, hypervisor. | ||
1197 | * Branches may straddle the kernel/user/hypervisor boundaries. | ||
1198 | * Thus, we have to try consecutively until we find a match | ||
1199 | * or else, the symbol is unknown | ||
1200 | */ | ||
1201 | thread__find_cpumode_addr_location(thread, machine, MAP__FUNCTION, ip, &al); | ||
1204 | 1202 | ||
1205 | for (i = 0; i < NCPUMODES; i++) { | ||
1206 | m = cpumodes[i]; | ||
1207 | /* | ||
1208 | * We cannot use the header.misc hint to determine whether a | ||
1209 | * branch stack address is user, kernel, guest, hypervisor. | ||
1210 | * Branches may straddle the kernel/user/hypervisor boundaries. | ||
1211 | * Thus, we have to try consecutively until we find a match | ||
1212 | * or else, the symbol is unknown | ||
1213 | */ | ||
1214 | thread__find_addr_location(thread, machine, m, MAP__FUNCTION, | ||
1215 | ip, &al); | ||
1216 | if (al.map) | ||
1217 | goto found; | ||
1218 | } | ||
1219 | found: | ||
1220 | ams->addr = ip; | 1203 | ams->addr = ip; |
1221 | ams->al_addr = al.addr; | 1204 | ams->al_addr = al.addr; |
1222 | ams->sym = al.sym; | 1205 | ams->sym = al.sym; |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 0358882c8910..3ce0498bdae6 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -142,3 +142,24 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp) | |||
142 | 142 | ||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | |||
146 | void thread__find_cpumode_addr_location(struct thread *thread, | ||
147 | struct machine *machine, | ||
148 | enum map_type type, u64 addr, | ||
149 | struct addr_location *al) | ||
150 | { | ||
151 | size_t i; | ||
152 | const u8 const cpumodes[] = { | ||
153 | PERF_RECORD_MISC_USER, | ||
154 | PERF_RECORD_MISC_KERNEL, | ||
155 | PERF_RECORD_MISC_GUEST_USER, | ||
156 | PERF_RECORD_MISC_GUEST_KERNEL | ||
157 | }; | ||
158 | |||
159 | for (i = 0; i < ARRAY_SIZE(cpumodes); i++) { | ||
160 | thread__find_addr_location(thread, machine, cpumodes[i], type, | ||
161 | addr, al); | ||
162 | if (al->map) | ||
163 | break; | ||
164 | } | ||
165 | } | ||
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 5b856bf942e1..9a070743270c 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
@@ -58,6 +58,11 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine, | |||
58 | u8 cpumode, enum map_type type, u64 addr, | 58 | u8 cpumode, enum map_type type, u64 addr, |
59 | struct addr_location *al); | 59 | struct addr_location *al); |
60 | 60 | ||
61 | void thread__find_cpumode_addr_location(struct thread *thread, | ||
62 | struct machine *machine, | ||
63 | enum map_type type, u64 addr, | ||
64 | struct addr_location *al); | ||
65 | |||
61 | static inline void *thread__priv(struct thread *thread) | 66 | static inline void *thread__priv(struct thread *thread) |
62 | { | 67 | { |
63 | return thread->priv; | 68 | return thread->priv; |