summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2018-11-06 16:07:10 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-12-17 12:54:13 -0500
commit8e80ad9983caeee09c3a0a1a37e05bff93becce4 (patch)
treed9043eaaaafb957bf1c8f4e1c665931fea6f6bda
parentec1891afae740be581ecf5abc8bda74c4549203f (diff)
perf thread: Add fallback functions for cases where cpumode is insufficient
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: Adrian 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: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/event.c27
-rw-r--r--tools/perf/util/machine.c27
-rw-r--r--tools/perf/util/machine.h2
-rw-r--r--tools/perf/util/thread.h4
4 files changed, 60 insertions, 0 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index e9c108a6b1c3..9431b20c1337 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1577,6 +1577,24 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
1577 return al->map; 1577 return al->map;
1578} 1578}
1579 1579
1580/*
1581 * For branch stacks or branch samples, the sample cpumode might not be correct
1582 * because it applies only to the sample 'ip' and not necessary to 'addr' or
1583 * branch stack addresses. If possible, use a fallback to deal with those cases.
1584 */
1585struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
1586 struct addr_location *al)
1587{
1588 struct map *map = thread__find_map(thread, cpumode, addr, al);
1589 struct machine *machine = thread->mg->machine;
1590 u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
1591
1592 if (map || addr_cpumode == cpumode)
1593 return map;
1594
1595 return thread__find_map(thread, addr_cpumode, addr, al);
1596}
1597
1580struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 1598struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
1581 u64 addr, struct addr_location *al) 1599 u64 addr, struct addr_location *al)
1582{ 1600{
@@ -1586,6 +1604,15 @@ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
1586 return al->sym; 1604 return al->sym;
1587} 1605}
1588 1606
1607struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
1608 u64 addr, struct addr_location *al)
1609{
1610 al->sym = NULL;
1611 if (thread__find_map_fb(thread, cpumode, addr, al))
1612 al->sym = map__find_symbol(al->map, al->addr);
1613 return al->sym;
1614}
1615
1589/* 1616/*
1590 * Callers need to drop the reference to al->thread, obtained in 1617 * Callers need to drop the reference to al->thread, obtained in
1591 * machine__findnew_thread() 1618 * machine__findnew_thread()
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 8f36ce813bc5..9397e3f2444d 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2592,6 +2592,33 @@ int machine__get_kernel_start(struct machine *machine)
2592 return err; 2592 return err;
2593} 2593}
2594 2594
2595u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
2596{
2597 u8 addr_cpumode = cpumode;
2598 bool kernel_ip;
2599
2600 if (!machine->single_address_space)
2601 goto out;
2602
2603 kernel_ip = machine__kernel_ip(machine, addr);
2604 switch (cpumode) {
2605 case PERF_RECORD_MISC_KERNEL:
2606 case PERF_RECORD_MISC_USER:
2607 addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
2608 PERF_RECORD_MISC_USER;
2609 break;
2610 case PERF_RECORD_MISC_GUEST_KERNEL:
2611 case PERF_RECORD_MISC_GUEST_USER:
2612 addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
2613 PERF_RECORD_MISC_GUEST_USER;
2614 break;
2615 default:
2616 break;
2617 }
2618out:
2619 return addr_cpumode;
2620}
2621
2595struct dso *machine__findnew_dso(struct machine *machine, const char *filename) 2622struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
2596{ 2623{
2597 return dsos__findnew(&machine->dsos, filename); 2624 return dsos__findnew(&machine->dsos, filename);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index ca897a73014c..ebde3ea70225 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(struct machine *machine, u64 ip)
100 return ip >= kernel_start; 100 return ip >= kernel_start;
101} 101}
102 102
103u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
104
103struct thread *machine__find_thread(struct machine *machine, pid_t pid, 105struct thread *machine__find_thread(struct machine *machine, pid_t pid,
104 pid_t tid); 106 pid_t tid);
105struct comm *machine__thread_exec_comm(struct machine *machine, 107struct comm *machine__thread_exec_comm(struct machine *machine,
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 30e2b4c165fe..5920c3bb8ffe 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -96,9 +96,13 @@ struct thread *thread__main_thread(struct machine *machine, struct thread *threa
96 96
97struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 97struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
98 struct addr_location *al); 98 struct addr_location *al);
99struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
100 struct addr_location *al);
99 101
100struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 102struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
101 u64 addr, struct addr_location *al); 103 u64 addr, struct addr_location *al);
104struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
105 u64 addr, struct addr_location *al);
102 106
103void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, 107void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
104 struct addr_location *al); 108 struct addr_location *al);