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/perf | |
| 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/perf')
| -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; |
