summaryrefslogtreecommitdiff
path: root/tools/perf/util/machine.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-12-12 11:09:52 +0300
committerIngo Molnar <mingo@kernel.org>2014-12-12 11:09:52 +0300
commit41e950c033b7df997d4b38653efe6554be9b96a7 (patch)
treeb8ffe779d47c768a9652ce9166f4878cee41f2ca /tools/perf/util/machine.c
parent3459f0d78ffe27a1b341c22eb158b622eaaea3fc (diff)
parente09b18d4907992d3d615b215c1abf585721b2810 (diff)
downloadlinux-41e950c033b7df997d4b38653efe6554be9b96a7.tar.xz
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Mark events as (x86 only) in help output for 'perf kvm stat live" (Alexander Yarygin) - Provide a better explanation when mmap fails in 'trace' (Arnaldo Carvalho de Melo) - Add --buildid-dir option to set cache directory, i.e. use: $ perf --buildid-dir /path/to/dir tool --tool-options (Jiri Olsa) - Fix memcpy/memset 'perf bench' output (Rabin Vicent) - Fix 'perf test' attr tests size values to cope with machine state on interrupt ABI changes (Jiri Olsa) - Fixup callchain type parameter handling error message (Kan Liang) Infrastructure changes and cleanups: - calloc/xcalloc: Fix argument order (Arjun Sreedharan) - Move filename__read_int from tools/perf/ to tools/lib, add sysctl__read_int there and use it in place of ad-hoc copies (Arnaldo Carvalho de Melo) - Use single strcmp call instead of two (Jiri Olsa) - Remove extra debugdir variables in 'perf buildid-cache' (Jiri Olsa) - Fix -a segfault related to kcore handling in 'perf buildid-cache' (Jiri Olsa) - Move cpumode resolve code to add_callchain_ip (Kan Liang) - Merge memset into memcpy 'perf bench' (Rabin Vincent) - Change print format from %lu to %PRIu64 in the hists browser (Tom Huynh) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r--tools/perf/util/machine.c72
1 files changed, 35 insertions, 37 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 15dd0a9691ce..94de3e48b490 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1385,19 +1385,46 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
static int add_callchain_ip(struct thread *thread,
struct symbol **parent,
struct addr_location *root_al,
- int cpumode,
+ bool branch_history,
u64 ip)
{
struct addr_location al;
al.filtered = 0;
al.sym = NULL;
- if (cpumode == -1)
+ if (branch_history)
thread__find_cpumode_addr_location(thread, MAP__FUNCTION,
ip, &al);
- else
+ else {
+ u8 cpumode = PERF_RECORD_MISC_USER;
+
+ if (ip >= PERF_CONTEXT_MAX) {
+ switch (ip) {
+ case PERF_CONTEXT_HV:
+ cpumode = PERF_RECORD_MISC_HYPERVISOR;
+ break;
+ case PERF_CONTEXT_KERNEL:
+ cpumode = PERF_RECORD_MISC_KERNEL;
+ break;
+ case PERF_CONTEXT_USER:
+ cpumode = PERF_RECORD_MISC_USER;
+ break;
+ default:
+ pr_debug("invalid callchain context: "
+ "%"PRId64"\n", (s64) ip);
+ /*
+ * It seems the callchain is corrupted.
+ * Discard all.
+ */
+ callchain_cursor_reset(&callchain_cursor);
+ return 1;
+ }
+ return 0;
+ }
thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
ip, &al);
+ }
+
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
symbol__match_regex(al.sym, &parent_regex))
@@ -1480,11 +1507,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
struct addr_location *root_al,
int max_stack)
{
- u8 cpumode = PERF_RECORD_MISC_USER;
int chain_nr = min(max_stack, (int)chain->nr);
- int i;
- int j;
- int err;
+ int i, j, err;
int skip_idx = -1;
int first_call = 0;
@@ -1542,10 +1566,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
for (i = 0; i < nr; i++) {
err = add_callchain_ip(thread, parent, root_al,
- -1, be[i].to);
+ true, be[i].to);
if (!err)
err = add_callchain_ip(thread, parent, root_al,
- -1, be[i].from);
+ true, be[i].from);
if (err == -EINVAL)
break;
if (err)
@@ -1574,36 +1598,10 @@ check_calls:
#endif
ip = chain->ips[j];
- if (ip >= PERF_CONTEXT_MAX) {
- switch (ip) {
- case PERF_CONTEXT_HV:
- cpumode = PERF_RECORD_MISC_HYPERVISOR;
- break;
- case PERF_CONTEXT_KERNEL:
- cpumode = PERF_RECORD_MISC_KERNEL;
- break;
- case PERF_CONTEXT_USER:
- cpumode = PERF_RECORD_MISC_USER;
- break;
- default:
- pr_debug("invalid callchain context: "
- "%"PRId64"\n", (s64) ip);
- /*
- * It seems the callchain is corrupted.
- * Discard all.
- */
- callchain_cursor_reset(&callchain_cursor);
- return 0;
- }
- continue;
- }
+ err = add_callchain_ip(thread, parent, root_al, false, ip);
- err = add_callchain_ip(thread, parent, root_al,
- cpumode, ip);
- if (err == -EINVAL)
- break;
if (err)
- return err;
+ return (err < 0) ? err : 0;
}
return 0;