aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/machine.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r--tools/perf/util/machine.c142
1 files changed, 89 insertions, 53 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 34fc7c8672e4..d97309c87bd6 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -21,7 +21,7 @@ static void dsos__init(struct dsos *dsos)
21 21
22int machine__init(struct machine *machine, const char *root_dir, pid_t pid) 22int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
23{ 23{
24 map_groups__init(&machine->kmaps); 24 map_groups__init(&machine->kmaps, machine);
25 RB_CLEAR_NODE(&machine->rb_node); 25 RB_CLEAR_NODE(&machine->rb_node);
26 dsos__init(&machine->user_dsos); 26 dsos__init(&machine->user_dsos);
27 dsos__init(&machine->kernel_dsos); 27 dsos__init(&machine->kernel_dsos);
@@ -32,7 +32,6 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
32 32
33 machine->vdso_info = NULL; 33 machine->vdso_info = NULL;
34 34
35 machine->kmaps.machine = machine;
36 machine->pid = pid; 35 machine->pid = pid;
37 36
38 machine->symbol_filter = NULL; 37 machine->symbol_filter = NULL;
@@ -319,7 +318,7 @@ static void machine__update_thread_pid(struct machine *machine,
319 goto out_err; 318 goto out_err;
320 319
321 if (!leader->mg) 320 if (!leader->mg)
322 leader->mg = map_groups__new(); 321 leader->mg = map_groups__new(machine);
323 322
324 if (!leader->mg) 323 if (!leader->mg)
325 goto out_err; 324 goto out_err;
@@ -465,6 +464,7 @@ struct map *machine__new_module(struct machine *machine, u64 start,
465{ 464{
466 struct map *map; 465 struct map *map;
467 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename); 466 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
467 bool compressed;
468 468
469 if (dso == NULL) 469 if (dso == NULL)
470 return NULL; 470 return NULL;
@@ -477,6 +477,11 @@ struct map *machine__new_module(struct machine *machine, u64 start,
477 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE; 477 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
478 else 478 else
479 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE; 479 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
480
481 /* _KMODULE_COMP should be next to _KMODULE */
482 if (is_kernel_module(filename, &compressed) && compressed)
483 dso->symtab_type++;
484
480 map_groups__insert(&machine->kmaps, map); 485 map_groups__insert(&machine->kmaps, map);
481 return map; 486 return map;
482} 487}
@@ -862,8 +867,14 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
862 struct map *map; 867 struct map *map;
863 char *long_name; 868 char *long_name;
864 869
865 if (dot == NULL || strcmp(dot, ".ko")) 870 if (dot == NULL)
866 continue; 871 continue;
872
873 /* On some system, modules are compressed like .ko.gz */
874 if (is_supported_compression(dot + 1) &&
875 is_kmodule_extension(dot - 2))
876 dot -= 3;
877
867 snprintf(dso_name, sizeof(dso_name), "[%.*s]", 878 snprintf(dso_name, sizeof(dso_name), "[%.*s]",
868 (int)(dot - dent->d_name), dent->d_name); 879 (int)(dot - dent->d_name), dent->d_name);
869 880
@@ -1045,6 +1056,11 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1045 dot = strrchr(name, '.'); 1056 dot = strrchr(name, '.');
1046 if (dot == NULL) 1057 if (dot == NULL)
1047 goto out_problem; 1058 goto out_problem;
1059 /* On some system, modules are compressed like .ko.gz */
1060 if (is_supported_compression(dot + 1))
1061 dot -= 3;
1062 if (!is_kmodule_extension(dot + 1))
1063 goto out_problem;
1048 snprintf(short_module_name, sizeof(short_module_name), 1064 snprintf(short_module_name, sizeof(short_module_name),
1049 "[%.*s]", (int)(dot - name), name); 1065 "[%.*s]", (int)(dot - name), name);
1050 strxfrchar(short_module_name, '-', '_'); 1066 strxfrchar(short_module_name, '-', '_');
@@ -1069,8 +1085,20 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1069 * Should be there already, from the build-id table in 1085 * Should be there already, from the build-id table in
1070 * the header. 1086 * the header.
1071 */ 1087 */
1072 struct dso *kernel = __dsos__findnew(&machine->kernel_dsos, 1088 struct dso *kernel = NULL;
1073 kmmap_prefix); 1089 struct dso *dso;
1090
1091 list_for_each_entry(dso, &machine->kernel_dsos.head, node) {
1092 if (is_kernel_module(dso->long_name, NULL))
1093 continue;
1094
1095 kernel = dso;
1096 break;
1097 }
1098
1099 if (kernel == NULL)
1100 kernel = __dsos__findnew(&machine->kernel_dsos,
1101 kmmap_prefix);
1074 if (kernel == NULL) 1102 if (kernel == NULL)
1075 goto out_problem; 1103 goto out_problem;
1076 1104
@@ -1078,6 +1106,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1078 if (__machine__create_kernel_maps(machine, kernel) < 0) 1106 if (__machine__create_kernel_maps(machine, kernel) < 0)
1079 goto out_problem; 1107 goto out_problem;
1080 1108
1109 if (strstr(dso->long_name, "vmlinux"))
1110 dso__set_short_name(dso, "[kernel.vmlinux]", false);
1111
1081 machine__set_kernel_mmap_len(machine, event); 1112 machine__set_kernel_mmap_len(machine, event);
1082 1113
1083 /* 1114 /*
@@ -1290,7 +1321,7 @@ static bool symbol__match_regex(struct symbol *sym, regex_t *regex)
1290 return 0; 1321 return 0;
1291} 1322}
1292 1323
1293static void ip__resolve_ams(struct machine *machine, struct thread *thread, 1324static void ip__resolve_ams(struct thread *thread,
1294 struct addr_map_symbol *ams, 1325 struct addr_map_symbol *ams,
1295 u64 ip) 1326 u64 ip)
1296{ 1327{
@@ -1304,7 +1335,7 @@ static void ip__resolve_ams(struct machine *machine, struct thread *thread,
1304 * Thus, we have to try consecutively until we find a match 1335 * Thus, we have to try consecutively until we find a match
1305 * or else, the symbol is unknown 1336 * or else, the symbol is unknown
1306 */ 1337 */
1307 thread__find_cpumode_addr_location(thread, machine, MAP__FUNCTION, ip, &al); 1338 thread__find_cpumode_addr_location(thread, MAP__FUNCTION, ip, &al);
1308 1339
1309 ams->addr = ip; 1340 ams->addr = ip;
1310 ams->al_addr = al.addr; 1341 ams->al_addr = al.addr;
@@ -1312,23 +1343,21 @@ static void ip__resolve_ams(struct machine *machine, struct thread *thread,
1312 ams->map = al.map; 1343 ams->map = al.map;
1313} 1344}
1314 1345
1315static void ip__resolve_data(struct machine *machine, struct thread *thread, 1346static void ip__resolve_data(struct thread *thread,
1316 u8 m, struct addr_map_symbol *ams, u64 addr) 1347 u8 m, struct addr_map_symbol *ams, u64 addr)
1317{ 1348{
1318 struct addr_location al; 1349 struct addr_location al;
1319 1350
1320 memset(&al, 0, sizeof(al)); 1351 memset(&al, 0, sizeof(al));
1321 1352
1322 thread__find_addr_location(thread, machine, m, MAP__VARIABLE, addr, 1353 thread__find_addr_location(thread, m, MAP__VARIABLE, addr, &al);
1323 &al);
1324 if (al.map == NULL) { 1354 if (al.map == NULL) {
1325 /* 1355 /*
1326 * some shared data regions have execute bit set which puts 1356 * some shared data regions have execute bit set which puts
1327 * their mapping in the MAP__FUNCTION type array. 1357 * their mapping in the MAP__FUNCTION type array.
1328 * Check there as a fallback option before dropping the sample. 1358 * Check there as a fallback option before dropping the sample.
1329 */ 1359 */
1330 thread__find_addr_location(thread, machine, m, MAP__FUNCTION, addr, 1360 thread__find_addr_location(thread, m, MAP__FUNCTION, addr, &al);
1331 &al);
1332 } 1361 }
1333 1362
1334 ams->addr = addr; 1363 ams->addr = addr;
@@ -1345,14 +1374,41 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
1345 if (!mi) 1374 if (!mi)
1346 return NULL; 1375 return NULL;
1347 1376
1348 ip__resolve_ams(al->machine, al->thread, &mi->iaddr, sample->ip); 1377 ip__resolve_ams(al->thread, &mi->iaddr, sample->ip);
1349 ip__resolve_data(al->machine, al->thread, al->cpumode, 1378 ip__resolve_data(al->thread, al->cpumode, &mi->daddr, sample->addr);
1350 &mi->daddr, sample->addr);
1351 mi->data_src.val = sample->data_src; 1379 mi->data_src.val = sample->data_src;
1352 1380
1353 return mi; 1381 return mi;
1354} 1382}
1355 1383
1384static int add_callchain_ip(struct thread *thread,
1385 struct symbol **parent,
1386 struct addr_location *root_al,
1387 int cpumode,
1388 u64 ip)
1389{
1390 struct addr_location al;
1391
1392 al.filtered = 0;
1393 al.sym = NULL;
1394 thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
1395 ip, &al);
1396 if (al.sym != NULL) {
1397 if (sort__has_parent && !*parent &&
1398 symbol__match_regex(al.sym, &parent_regex))
1399 *parent = al.sym;
1400 else if (have_ignore_callees && root_al &&
1401 symbol__match_regex(al.sym, &ignore_callees_regex)) {
1402 /* Treat this symbol as the root,
1403 forgetting its callees. */
1404 *root_al = al;
1405 callchain_cursor_reset(&callchain_cursor);
1406 }
1407 }
1408
1409 return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym);
1410}
1411
1356struct branch_info *sample__resolve_bstack(struct perf_sample *sample, 1412struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
1357 struct addr_location *al) 1413 struct addr_location *al)
1358{ 1414{
@@ -1364,15 +1420,14 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
1364 return NULL; 1420 return NULL;
1365 1421
1366 for (i = 0; i < bs->nr; i++) { 1422 for (i = 0; i < bs->nr; i++) {
1367 ip__resolve_ams(al->machine, al->thread, &bi[i].to, bs->entries[i].to); 1423 ip__resolve_ams(al->thread, &bi[i].to, bs->entries[i].to);
1368 ip__resolve_ams(al->machine, al->thread, &bi[i].from, bs->entries[i].from); 1424 ip__resolve_ams(al->thread, &bi[i].from, bs->entries[i].from);
1369 bi[i].flags = bs->entries[i].flags; 1425 bi[i].flags = bs->entries[i].flags;
1370 } 1426 }
1371 return bi; 1427 return bi;
1372} 1428}
1373 1429
1374static int machine__resolve_callchain_sample(struct machine *machine, 1430static int thread__resolve_callchain_sample(struct thread *thread,
1375 struct thread *thread,
1376 struct ip_callchain *chain, 1431 struct ip_callchain *chain,
1377 struct symbol **parent, 1432 struct symbol **parent,
1378 struct addr_location *root_al, 1433 struct addr_location *root_al,
@@ -1396,11 +1451,10 @@ static int machine__resolve_callchain_sample(struct machine *machine,
1396 * Based on DWARF debug information, some architectures skip 1451 * Based on DWARF debug information, some architectures skip
1397 * a callchain entry saved by the kernel. 1452 * a callchain entry saved by the kernel.
1398 */ 1453 */
1399 skip_idx = arch_skip_callchain_idx(machine, thread, chain); 1454 skip_idx = arch_skip_callchain_idx(thread, chain);
1400 1455
1401 for (i = 0; i < chain_nr; i++) { 1456 for (i = 0; i < chain_nr; i++) {
1402 u64 ip; 1457 u64 ip;
1403 struct addr_location al;
1404 1458
1405 if (callchain_param.order == ORDER_CALLEE) 1459 if (callchain_param.order == ORDER_CALLEE)
1406 j = i; 1460 j = i;
@@ -1437,24 +1491,10 @@ static int machine__resolve_callchain_sample(struct machine *machine,
1437 continue; 1491 continue;
1438 } 1492 }
1439 1493
1440 al.filtered = 0; 1494 err = add_callchain_ip(thread, parent, root_al,
1441 thread__find_addr_location(thread, machine, cpumode, 1495 cpumode, ip);
1442 MAP__FUNCTION, ip, &al); 1496 if (err == -EINVAL)
1443 if (al.sym != NULL) { 1497 break;
1444 if (sort__has_parent && !*parent &&
1445 symbol__match_regex(al.sym, &parent_regex))
1446 *parent = al.sym;
1447 else if (have_ignore_callees && root_al &&
1448 symbol__match_regex(al.sym, &ignore_callees_regex)) {
1449 /* Treat this symbol as the root,
1450 forgetting its callees. */
1451 *root_al = al;
1452 callchain_cursor_reset(&callchain_cursor);
1453 }
1454 }
1455
1456 err = callchain_cursor_append(&callchain_cursor,
1457 ip, al.map, al.sym);
1458 if (err) 1498 if (err)
1459 return err; 1499 return err;
1460 } 1500 }
@@ -1469,19 +1509,15 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
1469 entry->map, entry->sym); 1509 entry->map, entry->sym);
1470} 1510}
1471 1511
1472int machine__resolve_callchain(struct machine *machine, 1512int thread__resolve_callchain(struct thread *thread,
1473 struct perf_evsel *evsel, 1513 struct perf_evsel *evsel,
1474 struct thread *thread, 1514 struct perf_sample *sample,
1475 struct perf_sample *sample, 1515 struct symbol **parent,
1476 struct symbol **parent, 1516 struct addr_location *root_al,
1477 struct addr_location *root_al, 1517 int max_stack)
1478 int max_stack)
1479{ 1518{
1480 int ret; 1519 int ret = thread__resolve_callchain_sample(thread, sample->callchain,
1481 1520 parent, root_al, max_stack);
1482 ret = machine__resolve_callchain_sample(machine, thread,
1483 sample->callchain, parent,
1484 root_al, max_stack);
1485 if (ret) 1521 if (ret)
1486 return ret; 1522 return ret;
1487 1523
@@ -1495,7 +1531,7 @@ int machine__resolve_callchain(struct machine *machine,
1495 (!sample->user_stack.size)) 1531 (!sample->user_stack.size))
1496 return 0; 1532 return 0;
1497 1533
1498 return unwind__get_entries(unwind_entry, &callchain_cursor, machine, 1534 return unwind__get_entries(unwind_entry, &callchain_cursor,
1499 thread, sample, max_stack); 1535 thread, sample, max_stack);
1500 1536
1501} 1537}