From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933010AbeAIPhI (ORCPT + 1 other); Tue, 9 Jan 2018 10:37:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60164 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932883AbeAIPhE (ORCPT ); Tue, 9 Jan 2018 10:37:04 -0500 From: Jiri Olsa To: Arnaldo Carvalho de Melo Cc: Stephane Eranian , lkml , Ingo Molnar , Namhyung Kim , David Ahern , Andi Kleen , Alexander Shishkin , Peter Zijlstra Subject: [PATCH 27/49] perf tools: Use map_groups__find_addr_by_time() Date: Tue, 9 Jan 2018 16:35:00 +0100 Message-Id: <20180109153522.14116-28-jolsa@kernel.org> In-Reply-To: <20180109153522.14116-1-jolsa@kernel.org> References: <20180109153522.14116-1-jolsa@kernel.org> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 09 Jan 2018 15:37:04 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: From: Namhyung Kim Use timestamp to find a corresponding map so that it can find a match symbol eventually. Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-v4i4q9u41ab4hcjispe9qjzk@git.kernel.org Signed-off-by: Namhyung Kim Signed-off-by: Jiri Olsa --- tools/perf/util/event.c | 81 ++++++++++++++++++++++++++++++++++++++++++------ tools/perf/util/thread.c | 8 +++-- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 00e46ab1e432..5b53781a1bda 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1491,12 +1491,11 @@ int perf_event__process(struct perf_tool *tool __maybe_unused, return machine__process_event(machine, event, sample); } -static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, - enum map_type type, u64 addr, - struct addr_location *al) +static bool map_groups__set_addr_location(struct map_groups *mg, + struct addr_location *al, + u8 cpumode, u64 addr) { struct machine *machine = mg->machine; - bool load_map = false; al->machine = machine; al->addr = addr; @@ -1505,21 +1504,17 @@ static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, if (machine == NULL) { al->map = NULL; - return; + return true; } BUG_ON(mg == NULL); if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { al->level = 'k'; - mg = &machine->kmaps; - load_map = true; } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { al->level = '.'; } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { al->level = 'g'; - mg = &machine->kmaps; - load_map = true; } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { al->level = 'u'; } else { @@ -1535,8 +1530,27 @@ static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, !perf_host) al->filtered |= (1 << HIST_FILTER__HOST); + return true; + } + return false; +} + +static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al) +{ + struct machine *machine = mg->machine; + bool load_map = false; + + if (map_groups__set_addr_location(mg, al, cpumode, addr)) return; + + if ((cpumode == PERF_RECORD_MISC_KERNEL && perf_host) || + (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)) { + mg = &machine->kmaps; + load_map = true; } + try_again: al->map = map_groups__find(mg, type, al->addr); if (al->map == NULL) { @@ -1567,6 +1581,53 @@ static void map_groups__find_addr_map(struct map_groups *mg, u8 cpumode, } } +static void map_groups__find_addr_map_by_time(struct map_groups *mg, u8 cpumode, + enum map_type type, u64 addr, + struct addr_location *al, + u64 timestamp) +{ + struct machine *machine = mg->machine; + bool load_map = false; + + if (map_groups__set_addr_location(mg, al, cpumode, addr)) + return; + + if ((cpumode == PERF_RECORD_MISC_KERNEL && perf_host) || + (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)) { + mg = &machine->kmaps; + load_map = true; + } + +try_again: + al->map = map_groups__find_by_time(mg, type, al->addr, timestamp); + if (al->map == NULL) { + /* + * If this is outside of all known maps, and is a negative + * address, try to look it up in the kernel dso, as it might be + * a vsyscall or vdso (which executes in user-mode). + * + * XXX This is nasty, we should have a symbol list in the + * "[vdso]" dso, but for now lets use the old trick of looking + * in the whole kernel symbol list. + */ + if (cpumode == PERF_RECORD_MISC_USER && machine && + mg != &machine->kmaps && + machine__kernel_ip(machine, al->addr)) { + mg = &machine->kmaps; + load_map = true; + goto try_again; + } + } else { + /* + * Kernel maps might be changed when loading symbols so loading + * must be done prior to using kernel maps. + */ + if (load_map) + map__load(al->map); + al->addr = al->map->map_ip(al->map, al->addr); + } +} + void thread__find_addr_map(struct thread *thread, u8 cpumode, enum map_type type, u64 addr, struct addr_location *al) @@ -1587,7 +1648,7 @@ void thread__find_addr_map_by_time(struct thread *thread, u8 cpumode, mg = thread->mg; al->thread = thread; - map_groups__find_addr_map(mg, cpumode, type, addr, al); + map_groups__find_addr_map_by_time(mg, cpumode, type, addr, al, timestamp); } void thread__find_addr_location(struct thread *thread, diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index a05bee5b58b9..1ae211885c15 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -449,8 +449,12 @@ int thread__insert_map(struct thread *thread, struct map *map) if (ret) return ret; - map_groups__fixup_overlappings(thread->mg, map, stderr); - map_groups__insert(thread->mg, map); + if (perf_has_index) { + map_groups__insert_by_time(thread->mg, map); + } else { + map_groups__fixup_overlappings(thread->mg, map, stderr); + map_groups__insert(thread->mg, map); + } return 0; } -- 2.13.6