diff options
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r-- | tools/perf/util/machine.c | 46 |
1 files changed, 17 insertions, 29 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 813e94e7cf29..5cecd98c1bc0 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -327,9 +327,10 @@ struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, | |||
327 | return __machine__findnew_thread(machine, pid, tid, true); | 327 | return __machine__findnew_thread(machine, pid, tid, true); |
328 | } | 328 | } |
329 | 329 | ||
330 | struct thread *machine__find_thread(struct machine *machine, pid_t tid) | 330 | struct thread *machine__find_thread(struct machine *machine, pid_t pid, |
331 | pid_t tid) | ||
331 | { | 332 | { |
332 | return __machine__findnew_thread(machine, 0, tid, false); | 333 | return __machine__findnew_thread(machine, pid, tid, false); |
333 | } | 334 | } |
334 | 335 | ||
335 | int machine__process_comm_event(struct machine *machine, union perf_event *event, | 336 | int machine__process_comm_event(struct machine *machine, union perf_event *event, |
@@ -1114,7 +1115,9 @@ static void machine__remove_thread(struct machine *machine, struct thread *th) | |||
1114 | int machine__process_fork_event(struct machine *machine, union perf_event *event, | 1115 | int machine__process_fork_event(struct machine *machine, union perf_event *event, |
1115 | struct perf_sample *sample) | 1116 | struct perf_sample *sample) |
1116 | { | 1117 | { |
1117 | struct thread *thread = machine__find_thread(machine, event->fork.tid); | 1118 | struct thread *thread = machine__find_thread(machine, |
1119 | event->fork.pid, | ||
1120 | event->fork.tid); | ||
1118 | struct thread *parent = machine__findnew_thread(machine, | 1121 | struct thread *parent = machine__findnew_thread(machine, |
1119 | event->fork.ppid, | 1122 | event->fork.ppid, |
1120 | event->fork.ptid); | 1123 | event->fork.ptid); |
@@ -1140,7 +1143,9 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event | |||
1140 | int machine__process_exit_event(struct machine *machine, union perf_event *event, | 1143 | int machine__process_exit_event(struct machine *machine, union perf_event *event, |
1141 | struct perf_sample *sample __maybe_unused) | 1144 | struct perf_sample *sample __maybe_unused) |
1142 | { | 1145 | { |
1143 | struct thread *thread = machine__find_thread(machine, event->fork.tid); | 1146 | struct thread *thread = machine__find_thread(machine, |
1147 | event->fork.pid, | ||
1148 | event->fork.tid); | ||
1144 | 1149 | ||
1145 | if (dump_trace) | 1150 | if (dump_trace) |
1146 | perf_event__fprintf_task(event, stdout); | 1151 | perf_event__fprintf_task(event, stdout); |
@@ -1184,39 +1189,22 @@ static bool symbol__match_regex(struct symbol *sym, regex_t *regex) | |||
1184 | return 0; | 1189 | return 0; |
1185 | } | 1190 | } |
1186 | 1191 | ||
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, | 1192 | static void ip__resolve_ams(struct machine *machine, struct thread *thread, |
1196 | struct addr_map_symbol *ams, | 1193 | struct addr_map_symbol *ams, |
1197 | u64 ip) | 1194 | u64 ip) |
1198 | { | 1195 | { |
1199 | struct addr_location al; | 1196 | struct addr_location al; |
1200 | size_t i; | ||
1201 | u8 m; | ||
1202 | 1197 | ||
1203 | memset(&al, 0, sizeof(al)); | 1198 | memset(&al, 0, sizeof(al)); |
1199 | /* | ||
1200 | * We cannot use the header.misc hint to determine whether a | ||
1201 | * branch stack address is user, kernel, guest, hypervisor. | ||
1202 | * Branches may straddle the kernel/user/hypervisor boundaries. | ||
1203 | * Thus, we have to try consecutively until we find a match | ||
1204 | * or else, the symbol is unknown | ||
1205 | */ | ||
1206 | thread__find_cpumode_addr_location(thread, machine, MAP__FUNCTION, ip, &al); | ||
1204 | 1207 | ||
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; | 1208 | ams->addr = ip; |
1221 | ams->al_addr = al.addr; | 1209 | ams->al_addr = al.addr; |
1222 | ams->sym = al.sym; | 1210 | ams->sym = al.sym; |