aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/machine.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-06-08 02:24:07 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-06-08 02:24:07 -0400
commita292241cccb7e20e8b997a9a44177e7c98141859 (patch)
treea0b0bb95e7dce3233a2d8b203f9e326cdec7a00e /tools/perf/util/machine.c
parentd49cb7aeebb974713f9f7ab2991352d3050b095b (diff)
parent68807a0c2015cb40df4869e16651f0ce5cc14d52 (diff)
Merge branch 'next' into for-linus
Prepare input updates for 3.16.
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r--tools/perf/util/machine.c95
1 files changed, 44 insertions, 51 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index c872991e0f65..27c2a5efe450 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
330struct thread *machine__find_thread(struct machine *machine, pid_t tid) 330struct 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
335int machine__process_comm_event(struct machine *machine, union perf_event *event, 336int machine__process_comm_event(struct machine *machine, union perf_event *event,
@@ -716,7 +717,7 @@ static char *get_kernel_version(const char *root_dir)
716} 717}
717 718
718static int map_groups__set_modules_path_dir(struct map_groups *mg, 719static int map_groups__set_modules_path_dir(struct map_groups *mg,
719 const char *dir_name) 720 const char *dir_name, int depth)
720{ 721{
721 struct dirent *dent; 722 struct dirent *dent;
722 DIR *dir = opendir(dir_name); 723 DIR *dir = opendir(dir_name);
@@ -741,7 +742,15 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
741 !strcmp(dent->d_name, "..")) 742 !strcmp(dent->d_name, ".."))
742 continue; 743 continue;
743 744
744 ret = map_groups__set_modules_path_dir(mg, path); 745 /* Do not follow top-level source and build symlinks */
746 if (depth == 0) {
747 if (!strcmp(dent->d_name, "source") ||
748 !strcmp(dent->d_name, "build"))
749 continue;
750 }
751
752 ret = map_groups__set_modules_path_dir(mg, path,
753 depth + 1);
745 if (ret < 0) 754 if (ret < 0)
746 goto out; 755 goto out;
747 } else { 756 } else {
@@ -785,11 +794,11 @@ static int machine__set_modules_path(struct machine *machine)
785 if (!version) 794 if (!version)
786 return -1; 795 return -1;
787 796
788 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 797 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s",
789 machine->root_dir, version); 798 machine->root_dir, version);
790 free(version); 799 free(version);
791 800
792 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path); 801 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
793} 802}
794 803
795static int machine__create_module(void *arg, const char *name, u64 start) 804static int machine__create_module(void *arg, const char *name, u64 start)
@@ -1026,7 +1035,7 @@ int machine__process_mmap2_event(struct machine *machine,
1026 } 1035 }
1027 1036
1028 thread = machine__findnew_thread(machine, event->mmap2.pid, 1037 thread = machine__findnew_thread(machine, event->mmap2.pid,
1029 event->mmap2.pid); 1038 event->mmap2.tid);
1030 if (thread == NULL) 1039 if (thread == NULL)
1031 goto out_problem; 1040 goto out_problem;
1032 1041
@@ -1074,7 +1083,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
1074 } 1083 }
1075 1084
1076 thread = machine__findnew_thread(machine, event->mmap.pid, 1085 thread = machine__findnew_thread(machine, event->mmap.pid,
1077 event->mmap.pid); 1086 event->mmap.tid);
1078 if (thread == NULL) 1087 if (thread == NULL)
1079 goto out_problem; 1088 goto out_problem;
1080 1089
@@ -1114,7 +1123,9 @@ static void machine__remove_thread(struct machine *machine, struct thread *th)
1114int machine__process_fork_event(struct machine *machine, union perf_event *event, 1123int machine__process_fork_event(struct machine *machine, union perf_event *event,
1115 struct perf_sample *sample) 1124 struct perf_sample *sample)
1116{ 1125{
1117 struct thread *thread = machine__find_thread(machine, event->fork.tid); 1126 struct thread *thread = machine__find_thread(machine,
1127 event->fork.pid,
1128 event->fork.tid);
1118 struct thread *parent = machine__findnew_thread(machine, 1129 struct thread *parent = machine__findnew_thread(machine,
1119 event->fork.ppid, 1130 event->fork.ppid,
1120 event->fork.ptid); 1131 event->fork.ptid);
@@ -1140,7 +1151,9 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event
1140int machine__process_exit_event(struct machine *machine, union perf_event *event, 1151int machine__process_exit_event(struct machine *machine, union perf_event *event,
1141 struct perf_sample *sample __maybe_unused) 1152 struct perf_sample *sample __maybe_unused)
1142{ 1153{
1143 struct thread *thread = machine__find_thread(machine, event->fork.tid); 1154 struct thread *thread = machine__find_thread(machine,
1155 event->fork.pid,
1156 event->fork.tid);
1144 1157
1145 if (dump_trace) 1158 if (dump_trace)
1146 perf_event__fprintf_task(event, stdout); 1159 perf_event__fprintf_task(event, stdout);
@@ -1184,39 +1197,22 @@ static bool symbol__match_regex(struct symbol *sym, regex_t *regex)
1184 return 0; 1197 return 0;
1185} 1198}
1186 1199
1187static 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
1195static void ip__resolve_ams(struct machine *machine, struct thread *thread, 1200static void ip__resolve_ams(struct machine *machine, struct thread *thread,
1196 struct addr_map_symbol *ams, 1201 struct addr_map_symbol *ams,
1197 u64 ip) 1202 u64 ip)
1198{ 1203{
1199 struct addr_location al; 1204 struct addr_location al;
1200 size_t i;
1201 u8 m;
1202 1205
1203 memset(&al, 0, sizeof(al)); 1206 memset(&al, 0, sizeof(al));
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_cpumode_addr_location(thread, machine, MAP__FUNCTION, ip, &al);
1204 1215
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.sym)
1217 goto found;
1218 }
1219found:
1220 ams->addr = ip; 1216 ams->addr = ip;
1221 ams->al_addr = al.addr; 1217 ams->al_addr = al.addr;
1222 ams->sym = al.sym; 1218 ams->sym = al.sym;
@@ -1238,37 +1234,35 @@ static void ip__resolve_data(struct machine *machine, struct thread *thread,
1238 ams->map = al.map; 1234 ams->map = al.map;
1239} 1235}
1240 1236
1241struct mem_info *machine__resolve_mem(struct machine *machine, 1237struct mem_info *sample__resolve_mem(struct perf_sample *sample,
1242 struct thread *thr, 1238 struct addr_location *al)
1243 struct perf_sample *sample,
1244 u8 cpumode)
1245{ 1239{
1246 struct mem_info *mi = zalloc(sizeof(*mi)); 1240 struct mem_info *mi = zalloc(sizeof(*mi));
1247 1241
1248 if (!mi) 1242 if (!mi)
1249 return NULL; 1243 return NULL;
1250 1244
1251 ip__resolve_ams(machine, thr, &mi->iaddr, sample->ip); 1245 ip__resolve_ams(al->machine, al->thread, &mi->iaddr, sample->ip);
1252 ip__resolve_data(machine, thr, cpumode, &mi->daddr, sample->addr); 1246 ip__resolve_data(al->machine, al->thread, al->cpumode,
1247 &mi->daddr, sample->addr);
1253 mi->data_src.val = sample->data_src; 1248 mi->data_src.val = sample->data_src;
1254 1249
1255 return mi; 1250 return mi;
1256} 1251}
1257 1252
1258struct branch_info *machine__resolve_bstack(struct machine *machine, 1253struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
1259 struct thread *thr, 1254 struct addr_location *al)
1260 struct branch_stack *bs)
1261{ 1255{
1262 struct branch_info *bi;
1263 unsigned int i; 1256 unsigned int i;
1257 const struct branch_stack *bs = sample->branch_stack;
1258 struct branch_info *bi = calloc(bs->nr, sizeof(struct branch_info));
1264 1259
1265 bi = calloc(bs->nr, sizeof(struct branch_info));
1266 if (!bi) 1260 if (!bi)
1267 return NULL; 1261 return NULL;
1268 1262
1269 for (i = 0; i < bs->nr; i++) { 1263 for (i = 0; i < bs->nr; i++) {
1270 ip__resolve_ams(machine, thr, &bi[i].to, bs->entries[i].to); 1264 ip__resolve_ams(al->machine, al->thread, &bi[i].to, bs->entries[i].to);
1271 ip__resolve_ams(machine, thr, &bi[i].from, bs->entries[i].from); 1265 ip__resolve_ams(al->machine, al->thread, &bi[i].from, bs->entries[i].from);
1272 bi[i].flags = bs->entries[i].flags; 1266 bi[i].flags = bs->entries[i].flags;
1273 } 1267 }
1274 return bi; 1268 return bi;
@@ -1326,7 +1320,7 @@ static int machine__resolve_callchain_sample(struct machine *machine,
1326 continue; 1320 continue;
1327 } 1321 }
1328 1322
1329 al.filtered = false; 1323 al.filtered = 0;
1330 thread__find_addr_location(thread, machine, cpumode, 1324 thread__find_addr_location(thread, machine, cpumode,
1331 MAP__FUNCTION, ip, &al); 1325 MAP__FUNCTION, ip, &al);
1332 if (al.sym != NULL) { 1326 if (al.sym != NULL) {
@@ -1385,8 +1379,7 @@ int machine__resolve_callchain(struct machine *machine,
1385 return 0; 1379 return 0;
1386 1380
1387 return unwind__get_entries(unwind_entry, &callchain_cursor, machine, 1381 return unwind__get_entries(unwind_entry, &callchain_cursor, machine,
1388 thread, evsel->attr.sample_regs_user, 1382 thread, sample, max_stack);
1389 sample, max_stack);
1390 1383
1391} 1384}
1392 1385