From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752605AbbERAnF (ORCPT ); Sun, 17 May 2015 20:43:05 -0400 Received: from LGEMRELSE6Q.lge.com ([156.147.1.121]:55419 "EHLO lgemrelse6q.lge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752345AbbERAmJ (ORCPT ); Sun, 17 May 2015 20:42:09 -0400 X-Original-SENDERIP: 10.177.220.203 X-Original-MAILFROM: namhyung@kernel.org From: Namhyung Kim To: Arnaldo Carvalho de Melo Cc: Ingo Molnar , Peter Zijlstra , Jiri Olsa , LKML , David Ahern , Adrian Hunter , Andi Kleen , Frederic Weisbecker , Stephane Eranian Subject: [PATCH 23/40] perf tools: Use map_groups__find_addr_by_time() Date: Mon, 18 May 2015 09:30:38 +0900 Message-Id: <1431909055-21442-24-git-send-email-namhyung@kernel.org> X-Mailer: git-send-email 2.4.0 In-Reply-To: <1431909055-21442-1-git-send-email-namhyung@kernel.org> References: <1431909055-21442-1-git-send-email-namhyung@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use timestamp to find a corresponding map so that it can find a match symbol eventually. Cc: Stephane Eranian Signed-off-by: Namhyung Kim --- 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 bb391c20920d..930d45d5a37a 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -832,12 +832,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; @@ -846,21 +845,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 { @@ -876,8 +871,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) { @@ -908,6 +922,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, machine->symbol_filter); + 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) @@ -928,7 +989,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 e35cd18adc0e..3fa3e558316a 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -335,8 +335,12 @@ size_t thread__fprintf(struct thread *thread, FILE *fp) void thread__insert_map(struct thread *thread, struct map *map) { - 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); + } } static int thread__clone_map_groups(struct thread *thread, -- 2.4.0