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

Commit 0ada27a7 authored by Adrian Hunter's avatar Adrian Hunter Committed by Greg Kroah-Hartman
Browse files

perf thread: Add fallback functions for cases where cpumode is insufficient



commit 8e80ad9983caeee09c3a0a1a37e05bff93becce4 upstream.

For branch stacks or branch samples, the sample cpumode might not be
correct because it applies only to the sample 'ip' and not necessary to
'addr' or branch stack addresses. Add fallback functions that can be
used to deal with those cases

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: stable@vger.kernel.org # 4.19
Link: http://lkml.kernel.org/r/20181106210712.12098-2-adrian.hunter@intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 62977a9b
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -1576,6 +1576,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
	return al->map;
}

/*
 * For branch stacks or branch samples, the sample cpumode might not be correct
 * because it applies only to the sample 'ip' and not necessary to 'addr' or
 * branch stack addresses. If possible, use a fallback to deal with those cases.
 */
struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
				struct addr_location *al)
{
	struct map *map = thread__find_map(thread, cpumode, addr, al);
	struct machine *machine = thread->mg->machine;
	u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);

	if (map || addr_cpumode == cpumode)
		return map;

	return thread__find_map(thread, addr_cpumode, addr, al);
}

struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
				   u64 addr, struct addr_location *al)
{
@@ -1585,6 +1603,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
	return al->sym;
}

struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
				      u64 addr, struct addr_location *al)
{
	al->sym = NULL;
	if (thread__find_map_fb(thread, cpumode, addr, al))
		al->sym = map__find_symbol(al->map, al->addr);
	return al->sym;
}

/*
 * Callers need to drop the reference to al->thread, obtained in
 * machine__findnew_thread()
+27 −0
Original line number Diff line number Diff line
@@ -2575,6 +2575,33 @@ int machine__get_kernel_start(struct machine *machine)
	return err;
}

u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
{
	u8 addr_cpumode = cpumode;
	bool kernel_ip;

	if (!machine->single_address_space)
		goto out;

	kernel_ip = machine__kernel_ip(machine, addr);
	switch (cpumode) {
	case PERF_RECORD_MISC_KERNEL:
	case PERF_RECORD_MISC_USER:
		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
					   PERF_RECORD_MISC_USER;
		break;
	case PERF_RECORD_MISC_GUEST_KERNEL:
	case PERF_RECORD_MISC_GUEST_USER:
		addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
					   PERF_RECORD_MISC_GUEST_USER;
		break;
	default:
		break;
	}
out:
	return addr_cpumode;
}

struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
{
	return dsos__findnew(&machine->dsos, filename);
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
	return ip >= kernel_start;
}

u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);

struct thread *machine__find_thread(struct machine *machine, pid_t pid,
				    pid_t tid);
struct comm *machine__thread_exec_comm(struct machine *machine,
+4 −0
Original line number Diff line number Diff line
@@ -94,9 +94,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa

struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
			     struct addr_location *al);
struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
				struct addr_location *al);

struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
				   u64 addr, struct addr_location *al);
struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
				      u64 addr, struct addr_location *al);

void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
					struct addr_location *al);