perf callchain: Move cpumode resolve code to add_callchain_ip
authorKan Liang <kan.liang@intel.com>
Tue, 2 Dec 2014 15:06:53 +0000 (10:06 -0500)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 9 Dec 2014 13:06:29 +0000 (10:06 -0300)
Using flag to distinguish between branch_history and normal callchain.

Move the cpumode to add_callchain_ip function.

No change in behavior.

Signed-off-by: Kan Liang <kan.liang@intel.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1417532814-26208-3-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/machine.c

index 15dd0a9691ceea7efe0d091b43aa0c46b191061d..94de3e48b4909a03a7e7037f779074e5bf31ff8a 100644 (file)
@@ -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;