diff options
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 126 |
1 files changed, 68 insertions, 58 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f36d24a02445..5da6ce74c676 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -132,18 +132,18 @@ static void perf_session__delete_threads(struct perf_session *session) | |||
132 | 132 | ||
133 | static void perf_session_env__delete(struct perf_session_env *env) | 133 | static void perf_session_env__delete(struct perf_session_env *env) |
134 | { | 134 | { |
135 | free(env->hostname); | 135 | zfree(&env->hostname); |
136 | free(env->os_release); | 136 | zfree(&env->os_release); |
137 | free(env->version); | 137 | zfree(&env->version); |
138 | free(env->arch); | 138 | zfree(&env->arch); |
139 | free(env->cpu_desc); | 139 | zfree(&env->cpu_desc); |
140 | free(env->cpuid); | 140 | zfree(&env->cpuid); |
141 | 141 | ||
142 | free(env->cmdline); | 142 | zfree(&env->cmdline); |
143 | free(env->sibling_cores); | 143 | zfree(&env->sibling_cores); |
144 | free(env->sibling_threads); | 144 | zfree(&env->sibling_threads); |
145 | free(env->numa_nodes); | 145 | zfree(&env->numa_nodes); |
146 | free(env->pmu_mappings); | 146 | zfree(&env->pmu_mappings); |
147 | } | 147 | } |
148 | 148 | ||
149 | void perf_session__delete(struct perf_session *session) | 149 | void perf_session__delete(struct perf_session *session) |
@@ -247,27 +247,6 @@ void perf_tool__fill_defaults(struct perf_tool *tool) | |||
247 | } | 247 | } |
248 | } | 248 | } |
249 | 249 | ||
250 | void mem_bswap_32(void *src, int byte_size) | ||
251 | { | ||
252 | u32 *m = src; | ||
253 | while (byte_size > 0) { | ||
254 | *m = bswap_32(*m); | ||
255 | byte_size -= sizeof(u32); | ||
256 | ++m; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | void mem_bswap_64(void *src, int byte_size) | ||
261 | { | ||
262 | u64 *m = src; | ||
263 | |||
264 | while (byte_size > 0) { | ||
265 | *m = bswap_64(*m); | ||
266 | byte_size -= sizeof(u64); | ||
267 | ++m; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | static void swap_sample_id_all(union perf_event *event, void *data) | 250 | static void swap_sample_id_all(union perf_event *event, void *data) |
272 | { | 251 | { |
273 | void *end = (void *) event + event->header.size; | 252 | void *end = (void *) event + event->header.size; |
@@ -851,6 +830,7 @@ static struct machine * | |||
851 | struct perf_sample *sample) | 830 | struct perf_sample *sample) |
852 | { | 831 | { |
853 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 832 | const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
833 | struct machine *machine; | ||
854 | 834 | ||
855 | if (perf_guest && | 835 | if (perf_guest && |
856 | ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || | 836 | ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || |
@@ -863,7 +843,11 @@ static struct machine * | |||
863 | else | 843 | else |
864 | pid = sample->pid; | 844 | pid = sample->pid; |
865 | 845 | ||
866 | return perf_session__findnew_machine(session, pid); | 846 | machine = perf_session__find_machine(session, pid); |
847 | if (!machine) | ||
848 | machine = perf_session__findnew_machine(session, | ||
849 | DEFAULT_GUEST_KERNEL_ID); | ||
850 | return machine; | ||
867 | } | 851 | } |
868 | 852 | ||
869 | return &session->machines.host; | 853 | return &session->machines.host; |
@@ -1024,6 +1008,12 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
1024 | if (err == 0) | 1008 | if (err == 0) |
1025 | perf_session__set_id_hdr_size(session); | 1009 | perf_session__set_id_hdr_size(session); |
1026 | return err; | 1010 | return err; |
1011 | case PERF_RECORD_HEADER_EVENT_TYPE: | ||
1012 | /* | ||
1013 | * Depreceated, but we need to handle it for sake | ||
1014 | * of old data files create in pipe mode. | ||
1015 | */ | ||
1016 | return 0; | ||
1027 | case PERF_RECORD_HEADER_TRACING_DATA: | 1017 | case PERF_RECORD_HEADER_TRACING_DATA: |
1028 | /* setup for reading amidst mmap */ | 1018 | /* setup for reading amidst mmap */ |
1029 | lseek(fd, file_offset, SEEK_SET); | 1019 | lseek(fd, file_offset, SEEK_SET); |
@@ -1158,7 +1148,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session, | |||
1158 | void *buf = NULL; | 1148 | void *buf = NULL; |
1159 | int skip = 0; | 1149 | int skip = 0; |
1160 | u64 head; | 1150 | u64 head; |
1161 | int err; | 1151 | ssize_t err; |
1162 | void *p; | 1152 | void *p; |
1163 | 1153 | ||
1164 | perf_tool__fill_defaults(tool); | 1154 | perf_tool__fill_defaults(tool); |
@@ -1400,7 +1390,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg) | |||
1400 | { | 1390 | { |
1401 | struct perf_evsel *evsel; | 1391 | struct perf_evsel *evsel; |
1402 | 1392 | ||
1403 | list_for_each_entry(evsel, &session->evlist->entries, node) { | 1393 | evlist__for_each(session->evlist, evsel) { |
1404 | if (evsel->attr.type == PERF_TYPE_TRACEPOINT) | 1394 | if (evsel->attr.type == PERF_TYPE_TRACEPOINT) |
1405 | return true; | 1395 | return true; |
1406 | } | 1396 | } |
@@ -1458,7 +1448,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) | |||
1458 | 1448 | ||
1459 | ret += events_stats__fprintf(&session->stats, fp); | 1449 | ret += events_stats__fprintf(&session->stats, fp); |
1460 | 1450 | ||
1461 | list_for_each_entry(pos, &session->evlist->entries, node) { | 1451 | evlist__for_each(session->evlist, pos) { |
1462 | ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); | 1452 | ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); |
1463 | ret += events_stats__fprintf(&pos->hists.stats, fp); | 1453 | ret += events_stats__fprintf(&pos->hists.stats, fp); |
1464 | } | 1454 | } |
@@ -1480,35 +1470,30 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
1480 | { | 1470 | { |
1481 | struct perf_evsel *pos; | 1471 | struct perf_evsel *pos; |
1482 | 1472 | ||
1483 | list_for_each_entry(pos, &session->evlist->entries, node) { | 1473 | evlist__for_each(session->evlist, pos) { |
1484 | if (pos->attr.type == type) | 1474 | if (pos->attr.type == type) |
1485 | return pos; | 1475 | return pos; |
1486 | } | 1476 | } |
1487 | return NULL; | 1477 | return NULL; |
1488 | } | 1478 | } |
1489 | 1479 | ||
1490 | void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, | 1480 | void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, |
1491 | struct perf_sample *sample, struct machine *machine, | 1481 | struct addr_location *al, |
1492 | unsigned int print_opts, unsigned int stack_depth) | 1482 | unsigned int print_opts, unsigned int stack_depth) |
1493 | { | 1483 | { |
1494 | struct addr_location al; | ||
1495 | struct callchain_cursor_node *node; | 1484 | struct callchain_cursor_node *node; |
1496 | int print_ip = print_opts & PRINT_IP_OPT_IP; | 1485 | int print_ip = print_opts & PRINT_IP_OPT_IP; |
1497 | int print_sym = print_opts & PRINT_IP_OPT_SYM; | 1486 | int print_sym = print_opts & PRINT_IP_OPT_SYM; |
1498 | int print_dso = print_opts & PRINT_IP_OPT_DSO; | 1487 | int print_dso = print_opts & PRINT_IP_OPT_DSO; |
1499 | int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET; | 1488 | int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET; |
1500 | int print_oneline = print_opts & PRINT_IP_OPT_ONELINE; | 1489 | int print_oneline = print_opts & PRINT_IP_OPT_ONELINE; |
1490 | int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE; | ||
1501 | char s = print_oneline ? ' ' : '\t'; | 1491 | char s = print_oneline ? ' ' : '\t'; |
1502 | 1492 | ||
1503 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { | ||
1504 | error("problem processing %d event, skipping it.\n", | ||
1505 | event->header.type); | ||
1506 | return; | ||
1507 | } | ||
1508 | |||
1509 | if (symbol_conf.use_callchain && sample->callchain) { | 1493 | if (symbol_conf.use_callchain && sample->callchain) { |
1494 | struct addr_location node_al; | ||
1510 | 1495 | ||
1511 | if (machine__resolve_callchain(machine, evsel, al.thread, | 1496 | if (machine__resolve_callchain(al->machine, evsel, al->thread, |
1512 | sample, NULL, NULL, | 1497 | sample, NULL, NULL, |
1513 | PERF_MAX_STACK_DEPTH) != 0) { | 1498 | PERF_MAX_STACK_DEPTH) != 0) { |
1514 | if (verbose) | 1499 | if (verbose) |
@@ -1517,20 +1502,31 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, | |||
1517 | } | 1502 | } |
1518 | callchain_cursor_commit(&callchain_cursor); | 1503 | callchain_cursor_commit(&callchain_cursor); |
1519 | 1504 | ||
1505 | if (print_symoffset) | ||
1506 | node_al = *al; | ||
1507 | |||
1520 | while (stack_depth) { | 1508 | while (stack_depth) { |
1509 | u64 addr = 0; | ||
1510 | |||
1521 | node = callchain_cursor_current(&callchain_cursor); | 1511 | node = callchain_cursor_current(&callchain_cursor); |
1522 | if (!node) | 1512 | if (!node) |
1523 | break; | 1513 | break; |
1524 | 1514 | ||
1515 | if (node->sym && node->sym->ignore) | ||
1516 | goto next; | ||
1517 | |||
1525 | if (print_ip) | 1518 | if (print_ip) |
1526 | printf("%c%16" PRIx64, s, node->ip); | 1519 | printf("%c%16" PRIx64, s, node->ip); |
1527 | 1520 | ||
1521 | if (node->map) | ||
1522 | addr = node->map->map_ip(node->map, node->ip); | ||
1523 | |||
1528 | if (print_sym) { | 1524 | if (print_sym) { |
1529 | printf(" "); | 1525 | printf(" "); |
1530 | if (print_symoffset) { | 1526 | if (print_symoffset) { |
1531 | al.addr = node->ip; | 1527 | node_al.addr = addr; |
1532 | al.map = node->map; | 1528 | node_al.map = node->map; |
1533 | symbol__fprintf_symname_offs(node->sym, &al, stdout); | 1529 | symbol__fprintf_symname_offs(node->sym, &node_al, stdout); |
1534 | } else | 1530 | } else |
1535 | symbol__fprintf_symname(node->sym, stdout); | 1531 | symbol__fprintf_symname(node->sym, stdout); |
1536 | } | 1532 | } |
@@ -1541,39 +1537,49 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, | |||
1541 | printf(")"); | 1537 | printf(")"); |
1542 | } | 1538 | } |
1543 | 1539 | ||
1540 | if (print_srcline) | ||
1541 | map__fprintf_srcline(node->map, addr, "\n ", | ||
1542 | stdout); | ||
1543 | |||
1544 | if (!print_oneline) | 1544 | if (!print_oneline) |
1545 | printf("\n"); | 1545 | printf("\n"); |
1546 | 1546 | ||
1547 | callchain_cursor_advance(&callchain_cursor); | ||
1548 | |||
1549 | stack_depth--; | 1547 | stack_depth--; |
1548 | next: | ||
1549 | callchain_cursor_advance(&callchain_cursor); | ||
1550 | } | 1550 | } |
1551 | 1551 | ||
1552 | } else { | 1552 | } else { |
1553 | if (al->sym && al->sym->ignore) | ||
1554 | return; | ||
1555 | |||
1553 | if (print_ip) | 1556 | if (print_ip) |
1554 | printf("%16" PRIx64, sample->ip); | 1557 | printf("%16" PRIx64, sample->ip); |
1555 | 1558 | ||
1556 | if (print_sym) { | 1559 | if (print_sym) { |
1557 | printf(" "); | 1560 | printf(" "); |
1558 | if (print_symoffset) | 1561 | if (print_symoffset) |
1559 | symbol__fprintf_symname_offs(al.sym, &al, | 1562 | symbol__fprintf_symname_offs(al->sym, al, |
1560 | stdout); | 1563 | stdout); |
1561 | else | 1564 | else |
1562 | symbol__fprintf_symname(al.sym, stdout); | 1565 | symbol__fprintf_symname(al->sym, stdout); |
1563 | } | 1566 | } |
1564 | 1567 | ||
1565 | if (print_dso) { | 1568 | if (print_dso) { |
1566 | printf(" ("); | 1569 | printf(" ("); |
1567 | map__fprintf_dsoname(al.map, stdout); | 1570 | map__fprintf_dsoname(al->map, stdout); |
1568 | printf(")"); | 1571 | printf(")"); |
1569 | } | 1572 | } |
1573 | |||
1574 | if (print_srcline) | ||
1575 | map__fprintf_srcline(al->map, al->addr, "\n ", stdout); | ||
1570 | } | 1576 | } |
1571 | } | 1577 | } |
1572 | 1578 | ||
1573 | int perf_session__cpu_bitmap(struct perf_session *session, | 1579 | int perf_session__cpu_bitmap(struct perf_session *session, |
1574 | const char *cpu_list, unsigned long *cpu_bitmap) | 1580 | const char *cpu_list, unsigned long *cpu_bitmap) |
1575 | { | 1581 | { |
1576 | int i; | 1582 | int i, err = -1; |
1577 | struct cpu_map *map; | 1583 | struct cpu_map *map; |
1578 | 1584 | ||
1579 | for (i = 0; i < PERF_TYPE_MAX; ++i) { | 1585 | for (i = 0; i < PERF_TYPE_MAX; ++i) { |
@@ -1602,13 +1608,17 @@ int perf_session__cpu_bitmap(struct perf_session *session, | |||
1602 | if (cpu >= MAX_NR_CPUS) { | 1608 | if (cpu >= MAX_NR_CPUS) { |
1603 | pr_err("Requested CPU %d too large. " | 1609 | pr_err("Requested CPU %d too large. " |
1604 | "Consider raising MAX_NR_CPUS\n", cpu); | 1610 | "Consider raising MAX_NR_CPUS\n", cpu); |
1605 | return -1; | 1611 | goto out_delete_map; |
1606 | } | 1612 | } |
1607 | 1613 | ||
1608 | set_bit(cpu, cpu_bitmap); | 1614 | set_bit(cpu, cpu_bitmap); |
1609 | } | 1615 | } |
1610 | 1616 | ||
1611 | return 0; | 1617 | err = 0; |
1618 | |||
1619 | out_delete_map: | ||
1620 | cpu_map__delete(map); | ||
1621 | return err; | ||
1612 | } | 1622 | } |
1613 | 1623 | ||
1614 | void perf_session__fprintf_info(struct perf_session *session, FILE *fp, | 1624 | void perf_session__fprintf_info(struct perf_session *session, FILE *fp, |