aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2015-03-30 04:11:00 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-03-31 16:52:17 -0400
commit73dbcd6537f0ef6bf98d84f8fd7f8ab9994c6cd8 (patch)
tree2cfafaa079fc8e5bbb5508f62733461665ef3602 /tools
parent6ab2b762befd192b90704c5c7898f5abf8ebb387 (diff)
perf callchain: Fix kernel symbol resolution by remembering the cpumode
Commit 2e77784bb7d8 ("perf callchain: Move cpumode resolve code to add_callchain_ip") promised "No change in behavior.". As this commit breaks callchains on s390x (symbols not getting resolved, observed when profiling the kernel), this statement is wrong. The cpumode must be kept when iterating over all ips, otherwise the default (PERF_RECORD_MISC_USER) will be used by error. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1427703060-59883-1-git-send-email-dahi@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/machine.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e3353307330c..e45c8f33a8fd 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1408,29 +1408,27 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
1408static int add_callchain_ip(struct thread *thread, 1408static int add_callchain_ip(struct thread *thread,
1409 struct symbol **parent, 1409 struct symbol **parent,
1410 struct addr_location *root_al, 1410 struct addr_location *root_al,
1411 bool branch_history, 1411 u8 *cpumode,
1412 u64 ip) 1412 u64 ip)
1413{ 1413{
1414 struct addr_location al; 1414 struct addr_location al;
1415 1415
1416 al.filtered = 0; 1416 al.filtered = 0;
1417 al.sym = NULL; 1417 al.sym = NULL;
1418 if (branch_history) 1418 if (!cpumode) {
1419 thread__find_cpumode_addr_location(thread, MAP__FUNCTION, 1419 thread__find_cpumode_addr_location(thread, MAP__FUNCTION,
1420 ip, &al); 1420 ip, &al);
1421 else { 1421 } else {
1422 u8 cpumode = PERF_RECORD_MISC_USER;
1423
1424 if (ip >= PERF_CONTEXT_MAX) { 1422 if (ip >= PERF_CONTEXT_MAX) {
1425 switch (ip) { 1423 switch (ip) {
1426 case PERF_CONTEXT_HV: 1424 case PERF_CONTEXT_HV:
1427 cpumode = PERF_RECORD_MISC_HYPERVISOR; 1425 *cpumode = PERF_RECORD_MISC_HYPERVISOR;
1428 break; 1426 break;
1429 case PERF_CONTEXT_KERNEL: 1427 case PERF_CONTEXT_KERNEL:
1430 cpumode = PERF_RECORD_MISC_KERNEL; 1428 *cpumode = PERF_RECORD_MISC_KERNEL;
1431 break; 1429 break;
1432 case PERF_CONTEXT_USER: 1430 case PERF_CONTEXT_USER:
1433 cpumode = PERF_RECORD_MISC_USER; 1431 *cpumode = PERF_RECORD_MISC_USER;
1434 break; 1432 break;
1435 default: 1433 default:
1436 pr_debug("invalid callchain context: " 1434 pr_debug("invalid callchain context: "
@@ -1444,8 +1442,8 @@ static int add_callchain_ip(struct thread *thread,
1444 } 1442 }
1445 return 0; 1443 return 0;
1446 } 1444 }
1447 thread__find_addr_location(thread, cpumode, MAP__FUNCTION, 1445 thread__find_addr_location(thread, *cpumode, MAP__FUNCTION,
1448 ip, &al); 1446 ip, &al);
1449 } 1447 }
1450 1448
1451 if (al.sym != NULL) { 1449 if (al.sym != NULL) {
@@ -1538,6 +1536,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
1538{ 1536{
1539 struct ip_callchain *chain = sample->callchain; 1537 struct ip_callchain *chain = sample->callchain;
1540 int chain_nr = min(max_stack, (int)chain->nr); 1538 int chain_nr = min(max_stack, (int)chain->nr);
1539 u8 cpumode = PERF_RECORD_MISC_USER;
1541 int i, j, err; 1540 int i, j, err;
1542 u64 ip; 1541 u64 ip;
1543 1542
@@ -1584,7 +1583,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
1584 ip = lbr_stack->entries[0].to; 1583 ip = lbr_stack->entries[0].to;
1585 } 1584 }
1586 1585
1587 err = add_callchain_ip(thread, parent, root_al, false, ip); 1586 err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
1588 if (err) 1587 if (err)
1589 return (err < 0) ? err : 0; 1588 return (err < 0) ? err : 0;
1590 } 1589 }
@@ -1604,6 +1603,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1604 struct branch_stack *branch = sample->branch_stack; 1603 struct branch_stack *branch = sample->branch_stack;
1605 struct ip_callchain *chain = sample->callchain; 1604 struct ip_callchain *chain = sample->callchain;
1606 int chain_nr = min(max_stack, (int)chain->nr); 1605 int chain_nr = min(max_stack, (int)chain->nr);
1606 u8 cpumode = PERF_RECORD_MISC_USER;
1607 int i, j, err; 1607 int i, j, err;
1608 int skip_idx = -1; 1608 int skip_idx = -1;
1609 int first_call = 0; 1609 int first_call = 0;
@@ -1669,10 +1669,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1669 1669
1670 for (i = 0; i < nr; i++) { 1670 for (i = 0; i < nr; i++) {
1671 err = add_callchain_ip(thread, parent, root_al, 1671 err = add_callchain_ip(thread, parent, root_al,
1672 true, be[i].to); 1672 NULL, be[i].to);
1673 if (!err) 1673 if (!err)
1674 err = add_callchain_ip(thread, parent, root_al, 1674 err = add_callchain_ip(thread, parent, root_al,
1675 true, be[i].from); 1675 NULL, be[i].from);
1676 if (err == -EINVAL) 1676 if (err == -EINVAL)
1677 break; 1677 break;
1678 if (err) 1678 if (err)
@@ -1701,7 +1701,7 @@ check_calls:
1701#endif 1701#endif
1702 ip = chain->ips[j]; 1702 ip = chain->ips[j];
1703 1703
1704 err = add_callchain_ip(thread, parent, root_al, false, ip); 1704 err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
1705 1705
1706 if (err) 1706 if (err)
1707 return (err < 0) ? err : 0; 1707 return (err < 0) ? err : 0;