[RFC/PATCH 19/38] perf callchain: Use thread__find_addr_location_by_time() and friends
From: Namhyung Kim
Date: Fri Oct 02 2015 - 01:27:36 EST
Find correct thread/map/symbol using proper functions.
Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
tools/perf/util/machine.c | 25 ++++++++++++++++---------
tools/perf/util/unwind-libdw.c | 12 +++++++-----
tools/perf/util/unwind-libunwind.c | 27 ++++++++++++++-------------
3 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index d5e5b9de54b0..761b04b970ad 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1756,15 +1756,17 @@ static int add_callchain_ip(struct thread *thread,
struct symbol **parent,
struct addr_location *root_al,
u8 *cpumode,
- u64 ip)
+ u64 ip,
+ u64 timestamp)
{
struct addr_location al;
al.filtered = 0;
al.sym = NULL;
if (!cpumode) {
- thread__find_cpumode_addr_location(thread, MAP__FUNCTION,
- ip, &al);
+ thread__find_cpumode_addr_location_by_time(thread,
+ MAP__FUNCTION, ip,
+ &al, timestamp);
} else {
if (ip >= PERF_CONTEXT_MAX) {
switch (ip) {
@@ -1789,8 +1791,9 @@ static int add_callchain_ip(struct thread *thread,
}
return 0;
}
- thread__find_addr_location(thread, *cpumode, MAP__FUNCTION,
- ip, &al);
+ thread__find_addr_location_by_time(thread, *cpumode,
+ MAP__FUNCTION, ip,
+ &al, timestamp);
}
if (al.sym != NULL) {
@@ -1932,7 +1935,8 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
ip = lbr_stack->entries[0].to;
}
- err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+ err = add_callchain_ip(thread, parent, root_al, &cpumode, ip,
+ sample->time);
if (err)
return (err < 0) ? err : 0;
}
@@ -1953,6 +1957,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
struct ip_callchain *chain = sample->callchain;
int chain_nr = min(max_stack, (int)chain->nr);
u8 cpumode = PERF_RECORD_MISC_USER;
+ u64 timestamp = sample->time;
int i, j, err;
int skip_idx = -1;
int first_call = 0;
@@ -2018,10 +2023,11 @@ static int thread__resolve_callchain_sample(struct thread *thread,
for (i = 0; i < nr; i++) {
err = add_callchain_ip(thread, parent, root_al,
- NULL, be[i].to);
+ NULL, be[i].to, timestamp);
if (!err)
err = add_callchain_ip(thread, parent, root_al,
- NULL, be[i].from);
+ NULL, be[i].from,
+ timestamp);
if (err == -EINVAL)
break;
if (err)
@@ -2050,7 +2056,8 @@ check_calls:
#endif
ip = chain->ips[j];
- err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+ err = add_callchain_ip(thread, parent, root_al, &cpumode, ip,
+ timestamp);
if (err)
return (err < 0) ? err : 0;
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 2dcfe9a7c8d0..0dd2b6ff4093 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -26,9 +26,9 @@ static int __report_module(struct addr_location *al, u64 ip,
Dwfl_Module *mod;
struct dso *dso = NULL;
- thread__find_addr_location(ui->thread,
- PERF_RECORD_MISC_USER,
- MAP__FUNCTION, ip, al);
+ thread__find_addr_location_by_time(ui->thread, PERF_RECORD_MISC_USER,
+ MAP__FUNCTION, ip, al,
+ ui->sample->time);
if (al->map)
dso = al->map->dso;
@@ -89,8 +89,10 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr,
struct addr_location al;
ssize_t size;
- thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
- MAP__FUNCTION, addr, &al);
+ thread__find_addr_map_by_time(ui->thread, PERF_RECORD_MISC_USER,
+ MAP__FUNCTION, addr, &al,
+ ui->sample->time);
+
if (!al.map) {
pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
return -1;
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 4c00507ee3fd..5cac2dd68688 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -317,8 +317,10 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
{
struct addr_location al;
- thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
- MAP__FUNCTION, ip, &al);
+ thread__find_addr_map_by_time(ui->thread, PERF_RECORD_MISC_USER,
+ MAP__FUNCTION, ip, &al,
+ ui->sample->time);
+
return al.map;
}
@@ -411,20 +413,19 @@ get_proc_name(unw_addr_space_t __maybe_unused as,
static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
unw_word_t *data)
{
- struct addr_location al;
+ struct map *map;
ssize_t size;
- thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
- MAP__FUNCTION, addr, &al);
- if (!al.map) {
+ map = find_map(addr, ui);
+ if (!map) {
pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
return -1;
}
- if (!al.map->dso)
+ if (!map->dso)
return -1;
- size = dso__data_read_addr(al.map->dso, al.map, ui->machine,
+ size = dso__data_read_addr(map->dso, map, ui->machine,
addr, (u8 *) data, sizeof(*data));
return !(size == sizeof(*data));
@@ -516,14 +517,14 @@ static void put_unwind_info(unw_addr_space_t __maybe_unused as,
pr_debug("unwind: put_unwind_info called\n");
}
-static int entry(u64 ip, struct thread *thread,
+static int entry(u64 ip, struct thread *thread, u64 timestamp,
unwind_entry_cb_t cb, void *arg)
{
struct unwind_entry e;
struct addr_location al;
- thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
- MAP__FUNCTION, ip, &al);
+ thread__find_addr_location_by_time(thread, PERF_RECORD_MISC_USER,
+ MAP__FUNCTION, ip, &al, timestamp);
e.ip = ip;
e.map = al.map;
@@ -625,7 +626,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
unw_word_t ip;
unw_get_reg(&c, UNW_REG_IP, &ip);
- ret = ip ? entry(ip, ui->thread, cb, arg) : 0;
+ ret = ip ? entry(ip, ui->thread, ui->sample->time, cb, arg) : 0;
}
return ret;
@@ -650,7 +651,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
if (ret)
return ret;
- ret = entry(ip, thread, cb, arg);
+ ret = entry(ip, thread, data->time, cb, arg);
if (ret)
return -ENOMEM;
--
2.6.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/