Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e77784b authored by Kan Liang's avatar Kan Liang Committed by Arnaldo Carvalho de Melo
Browse files

perf callchain: Move cpumode resolve code to add_callchain_ip



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: default avatarKan Liang <kan.liang@intel.com>
Acked-by: default avatarJiri 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f70b4e39
Loading
Loading
Loading
Loading
+35 −37
Original line number Diff line number Diff line
@@ -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 @@ static int thread__resolve_callchain_sample(struct thread *thread,
#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;