lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <1443763159-29098-26-git-send-email-namhyung@kernel.org> Date: Fri, 2 Oct 2015 14:19:06 +0900 From: Namhyung Kim <namhyung@...nel.org> To: Arnaldo Carvalho de Melo <acme@...nel.org> Cc: Ingo Molnar <mingo@...nel.org>, Peter Zijlstra <a.p.zijlstra@...llo.nl>, Jiri Olsa <jolsa@...hat.com>, LKML <linux-kernel@...r.kernel.org>, Frederic Weisbecker <fweisbec@...il.com>, Stephane Eranian <eranian@...gle.com>, David Ahern <dsahern@...il.com>, Andi Kleen <andi@...stfloor.org> Subject: [RFC/PATCH 25/38] perf callchain: Maintain libunwind's address space in map_groups Currently the address_space was kept in thread struct but it's more appropriate to keep it in map_groups as it's maintained throughout exec's with timestamps. Also we should not flush the address space after exec since it still can be accessed when used with an indexed data file. Cc: Frederic Weisbecker <fweisbec@...il.com> Signed-off-by: Namhyung Kim <namhyung@...nel.org> --- tools/perf/tests/dwarf-unwind.c | 5 +++-- tools/perf/util/map.c | 5 +++++ tools/perf/util/map.h | 1 + tools/perf/util/thread.c | 7 ------- tools/perf/util/unwind-libunwind.c | 28 +++++++++++++--------------- tools/perf/util/unwind.h | 15 ++++++--------- 6 files changed, 28 insertions(+), 33 deletions(-) diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index b9ca0a72fc4d..c3774e0ebcf4 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -143,6 +143,9 @@ int test__dwarf_unwind(void) struct thread *thread; int err = -1; + /* The record_mode should be set before calling map_groups__init() */ + callchain_param.record_mode = CALLCHAIN_DWARF; + machines__init(&machines); machine = machines__find(&machines, HOST_KERNEL_ID); @@ -151,8 +154,6 @@ int test__dwarf_unwind(void) return -1; } - callchain_param.record_mode = CALLCHAIN_DWARF; - if (init_live_machine(machine)) { pr_err("Could not init machine\n"); goto out; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index c0f8933f29f0..c458a40f8d26 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -14,6 +14,7 @@ #include "util.h" #include "debug.h" #include "machine.h" +#include "unwind.h" #include <linux/string.h> static void __maps__insert(struct maps *maps, struct map *map); @@ -475,6 +476,8 @@ void map_groups__init(struct map_groups *mg, struct machine *machine) atomic_set(&mg->refcnt, 1); mg->timestamp = 0; INIT_LIST_HEAD(&mg->list); + + unwind__prepare_access(mg); } static void __maps__purge(struct maps *maps) @@ -504,6 +507,8 @@ void map_groups__exit(struct map_groups *mg) for (i = 0; i < MAP__NR_TYPES; ++i) maps__exit(&mg->maps[i]); + + unwind__finish_access(mg); } bool map_groups__empty(struct map_groups *mg) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 41a9a39f1027..ef3f8b1649ab 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -73,6 +73,7 @@ struct map_groups { atomic_t refcnt; u64 timestamp; struct list_head list; + void *priv; }; struct map_groups *map_groups__new(struct machine *machine); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 21de681415f4..05aaf7d0ad18 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -107,9 +107,6 @@ struct thread *thread__new(pid_t pid, pid_t tid) INIT_LIST_HEAD(&thread->comm_list); INIT_LIST_HEAD(&thread->mg_list); - if (unwind__prepare_access(thread) < 0) - goto err_thread; - comm_str = malloc(32); if (!comm_str) goto err_thread; @@ -155,7 +152,6 @@ void thread__delete(struct thread *thread) list_del(&comm->list); comm__free(comm); } - unwind__finish_access(thread); free(thread); } @@ -252,9 +248,6 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, break; } list_add_tail(&new->list, &curr->list); - - if (exec) - unwind__flush_access(thread); } if (exec) { diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 5cac2dd68688..5cad1aecf051 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -32,6 +32,7 @@ #include "symbol.h" #include "util.h" #include "debug.h" +#include "map.h" extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, @@ -566,7 +567,7 @@ static unw_accessors_t accessors = { .get_proc_name = get_proc_name, }; -int unwind__prepare_access(struct thread *thread) +int unwind__prepare_access(struct map_groups *mg) { unw_addr_space_t addr_space; @@ -580,41 +581,38 @@ int unwind__prepare_access(struct thread *thread) } unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL); - thread__set_priv(thread, addr_space); + mg->priv = addr_space; return 0; } -void unwind__flush_access(struct thread *thread) +void unwind__finish_access(struct map_groups *mg) { - unw_addr_space_t addr_space; + unw_addr_space_t addr_space = mg->priv; if (callchain_param.record_mode != CALLCHAIN_DWARF) return; - addr_space = thread__priv(thread); - unw_flush_cache(addr_space, 0, 0); -} - -void unwind__finish_access(struct thread *thread) -{ - unw_addr_space_t addr_space; - - if (callchain_param.record_mode != CALLCHAIN_DWARF) + if (addr_space == NULL) return; - addr_space = thread__priv(thread); unw_destroy_addr_space(addr_space); + mg->priv = NULL; } static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, void *arg, int max_stack) { + struct map_groups *mg; unw_addr_space_t addr_space; unw_cursor_t c; int ret; - addr_space = thread__priv(ui->thread); + mg = thread__get_map_groups(ui->thread, ui->sample->time); + if (mg == NULL) + return -1; + + addr_space = mg->priv; if (addr_space == NULL) return -1; diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index 12790cf94618..c6860b481d07 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -21,17 +21,15 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, /* libunwind specific */ #ifdef HAVE_LIBUNWIND_SUPPORT int libunwind__arch_reg_id(int regnum); -int unwind__prepare_access(struct thread *thread); -void unwind__flush_access(struct thread *thread); -void unwind__finish_access(struct thread *thread); +int unwind__prepare_access(struct map_groups *mg); +void unwind__finish_access(struct map_groups *mg); #else -static inline int unwind__prepare_access(struct thread *thread __maybe_unused) +static inline int unwind__prepare_access(struct map_groups *mg __maybe_unused) { return 0; } -static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} -static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} +static inline void unwind__finish_access(struct map_groups *mg __maybe_unused) {} #endif #else static inline int @@ -44,12 +42,11 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, return 0; } -static inline int unwind__prepare_access(struct thread *thread __maybe_unused) +static inline int unwind__prepare_access(struct map_groups *mg __maybe_unused) { return 0; } -static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} -static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} +static inline void unwind__finish_access(struct map_groups *mg __maybe_unused) {} #endif /* HAVE_DWARF_UNWIND_SUPPORT */ #endif /* __UNWIND_H */ -- 2.6.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists