[PATCH 19/37] perf tools: Introduce thread__find_addr_location_time() and friends
The *_time() variants are for find appropriate map (and symbol) at the given time. This is based on the fact that map_groups list is sorted by time in the previous patch. Cc: Frederic Weisbecker Signed-off-by: Namhyung Kim --- tools/perf/util/event.c| 59 ++ tools/perf/util/machine.c | 51 ++-- tools/perf/util/thread.c | 21 ++ tools/perf/util/thread.h | 10 +++ tools/perf/util/unwind-libdw.c | 11 +++ tools/perf/util/unwind-libunwind.c | 18 ++-- 6 files changed, 129 insertions(+), 41 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2d04949bdc7d..3bb186a26314 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -731,16 +731,14 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, return machine__process_event(machine, event, sample); } -void thread__find_addr_map(struct thread *thread, u8 cpumode, - enum map_type type, u64 addr, - struct addr_location *al) +static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al) { - struct map_groups *mg = thread->mg; struct machine *machine = mg->machine; bool load_map = false; al->machine = machine; - al->thread = thread; al->addr = addr; al->cpumode = cpumode; al->filtered = 0; @@ -809,6 +807,35 @@ void thread__find_addr_map(struct thread *thread, u8 cpumode, } } +void thread__find_addr_map(struct thread *thread, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al) +{ + al->thread = thread; + map_groups__find_addr_map(thread->mg, cpumode, type, addr, al); +} + +void thread__find_addr_map_time(struct thread *thread, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al, u64 timestamp) +{ + struct map_groups *mg; + struct thread *leader; + + if (thread->tid == thread->pid_) + leader = thread; + else + leader = machine__find_thread(thread->mg->machine, + thread->pid_, thread->pid_); + + BUG_ON(leader == NULL); + + mg = thread__get_map_groups(leader, timestamp); + + al->thread = thread; + map_groups__find_addr_map(mg, cpumode, type, addr, al); +} + void thread__find_addr_location(struct thread *thread, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al) @@ -821,6 +848,21 @@ void thread__find_addr_location(struct thread *thread, al->sym = NULL; } +void thread__find_addr_location_time(struct thread *thread, u8 cpumode, +enum map_type type, u64 addr, +struct addr_location *al, u64 timestamp) +{ + struct map_groups *mg; + + mg = thread__get_map_groups(thread, timestamp); + map_groups__find_addr_map(mg, cpumode, type, addr, al); + if (al->map != NULL) + al->sym = map__find_symbol(al->map, al->addr, + mg->machine->symbol_filter); + else + al->sym = NULL; +} + int perf_event__preprocess_sample(const union perf_event *event, struct machine *machine, struct addr_location *al, @@ -845,7 +887,12 @@ int perf_event__preprocess_sample(const union perf_event *event, machine->vmlinux_maps[MAP__FUNCTION] == NULL) machine__create_kernel_maps(machine); - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al); + /* +* sample->time is -1ULL if !PERF_SAMPLE_TIME which ends up +* with using most recent map_groups (same as default behavior). +*/ + thread__find_addr_map_time(thread, cpumode, MAP__FUNCTION, sample->ip, + al, sample->time); dump_printf(" .. dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : ""); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index beae6e8fe789..ffce0bcd2d9a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1466,7 +1466,7 @@ static bool symbol__match_regex(struct symbol *sym, regex_t *regex) static void ip__resolve_ams(struct thread *thread, struct addr_map_symbol *ams, - u64 ip) + u64 ip, u64 timestamp) { struct addr_location al; @@
[PATCH 19/37] perf tools: Introduce thread__find_addr_location_time() and friends
The *_time() variants are for find appropriate map (and symbol) at the given time. This is based on the fact that map_groups list is sorted by time in the previous patch. Cc: Frederic Weisbecker fweis...@gmail.com Signed-off-by: Namhyung Kim namhy...@kernel.org --- tools/perf/util/event.c| 59 ++ tools/perf/util/machine.c | 51 ++-- tools/perf/util/thread.c | 21 ++ tools/perf/util/thread.h | 10 +++ tools/perf/util/unwind-libdw.c | 11 +++ tools/perf/util/unwind-libunwind.c | 18 ++-- 6 files changed, 129 insertions(+), 41 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2d04949bdc7d..3bb186a26314 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -731,16 +731,14 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, return machine__process_event(machine, event, sample); } -void thread__find_addr_map(struct thread *thread, u8 cpumode, - enum map_type type, u64 addr, - struct addr_location *al) +static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al) { - struct map_groups *mg = thread-mg; struct machine *machine = mg-machine; bool load_map = false; al-machine = machine; - al-thread = thread; al-addr = addr; al-cpumode = cpumode; al-filtered = 0; @@ -809,6 +807,35 @@ void thread__find_addr_map(struct thread *thread, u8 cpumode, } } +void thread__find_addr_map(struct thread *thread, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al) +{ + al-thread = thread; + map_groups__find_addr_map(thread-mg, cpumode, type, addr, al); +} + +void thread__find_addr_map_time(struct thread *thread, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al, u64 timestamp) +{ + struct map_groups *mg; + struct thread *leader; + + if (thread-tid == thread-pid_) + leader = thread; + else + leader = machine__find_thread(thread-mg-machine, + thread-pid_, thread-pid_); + + BUG_ON(leader == NULL); + + mg = thread__get_map_groups(leader, timestamp); + + al-thread = thread; + map_groups__find_addr_map(mg, cpumode, type, addr, al); +} + void thread__find_addr_location(struct thread *thread, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al) @@ -821,6 +848,21 @@ void thread__find_addr_location(struct thread *thread, al-sym = NULL; } +void thread__find_addr_location_time(struct thread *thread, u8 cpumode, +enum map_type type, u64 addr, +struct addr_location *al, u64 timestamp) +{ + struct map_groups *mg; + + mg = thread__get_map_groups(thread, timestamp); + map_groups__find_addr_map(mg, cpumode, type, addr, al); + if (al-map != NULL) + al-sym = map__find_symbol(al-map, al-addr, + mg-machine-symbol_filter); + else + al-sym = NULL; +} + int perf_event__preprocess_sample(const union perf_event *event, struct machine *machine, struct addr_location *al, @@ -845,7 +887,12 @@ int perf_event__preprocess_sample(const union perf_event *event, machine-vmlinux_maps[MAP__FUNCTION] == NULL) machine__create_kernel_maps(machine); - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample-ip, al); + /* +* sample-time is -1ULL if !PERF_SAMPLE_TIME which ends up +* with using most recent map_groups (same as default behavior). +*/ + thread__find_addr_map_time(thread, cpumode, MAP__FUNCTION, sample-ip, + al, sample-time); dump_printf( .. dso: %s\n, al-map ? al-map-dso-long_name : al-level == 'H' ? [hypervisor] : not found); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index beae6e8fe789..ffce0bcd2d9a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1466,7 +1466,7 @@ static bool symbol__match_regex(struct symbol *sym, regex_t *regex) static void ip__resolve_ams(struct thread *thread, struct addr_map_symbol *ams, - u64 ip) + u64 ip, u64 timestamp) { struct addr_location al;