lkml.org 
[lkml]   [2018]   [Sep]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH 29/48] perf callchain: Maintain libunwind's address space in map_groups
    Em Thu, Sep 13, 2018 at 02:54:31PM +0200, Jiri Olsa escreveu:
    > 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@gmail.com>
    > Link: http://lkml.kernel.org/n/tip-hjryh6x2yfnrz8g0djhez24z@git.kernel.org
    > Signed-off-by: Namhyung Kim <namhyung@kernel.org>
    > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    > ---
    > tools/perf/util/map.h | 5 ++++-
    > tools/perf/util/thread.h | 1 -
    > tools/perf/util/unwind-libunwind-local.c | 28 ++++++++++++++----------
    > tools/perf/util/unwind-libunwind.c | 9 ++++----
    > tools/perf/util/unwind.h | 7 +++---
    > 5 files changed, 29 insertions(+), 21 deletions(-)
    >
    > diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
    > index 02c6f6962eb1..b1efe57b8563 100644
    > --- a/tools/perf/util/map.h
    > +++ b/tools/perf/util/map.h
    > @@ -65,10 +65,13 @@ struct maps {
    >
    > struct map_groups {
    > struct maps maps;
    > - struct machine *machine;
    > + struct machine *machine;
    > refcount_t refcnt;
    > u64 timestamp;
    > struct list_head list;

    Hey, avoid these distractions, this doesn't change anything and besides
    having the * aligned with the names of non-pointers is what is common
    practice, see for instance 'struct task_struct', 'struct inode', to name
    just two widely used structs in the kernel source :-)

    I'll get these two fixed up, i.e. remove the above hunk, align the one
    below :-)

    - Arnaldo

    > +#ifdef HAVE_LIBUNWIND_SUPPORT
    > + void *addr_space;
    > +#endif
    > };
    >
    > struct map_groups *map_groups__new(struct machine *machine);
    > diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
    > index 86186a0773a0..637775f622b3 100644
    > --- a/tools/perf/util/thread.h
    > +++ b/tools/perf/util/thread.h
    > @@ -40,7 +40,6 @@ struct thread {
    > struct thread_stack *ts;
    > struct nsinfo *nsinfo;
    > #ifdef HAVE_LIBUNWIND_SUPPORT
    > - void *addr_space;
    > struct unwind_libunwind_ops *unwind_libunwind_ops;
    > #endif
    > };
    > diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
    > index da6f39315b47..f7c921f87bcf 100644
    > --- a/tools/perf/util/unwind-libunwind-local.c
    > +++ b/tools/perf/util/unwind-libunwind-local.c
    > @@ -617,32 +617,35 @@ static unw_accessors_t accessors = {
    > .get_proc_name = get_proc_name,
    > };
    >
    > -static int _unwind__prepare_access(struct thread *thread)
    > +static int _unwind__prepare_access(struct map_groups *mg)
    > {
    > if (!dwarf_callchain_users)
    > return 0;
    > - thread->addr_space = unw_create_addr_space(&accessors, 0);
    > - if (!thread->addr_space) {
    > +
    > + mg->addr_space = unw_create_addr_space(&accessors, 0);
    > + if (!mg->addr_space) {
    > pr_err("unwind: Can't create unwind address space.\n");
    > return -ENOMEM;
    > }
    >
    > - unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
    > + unw_set_caching_policy(mg->addr_space, UNW_CACHE_GLOBAL);
    > return 0;
    > }
    >
    > -static void _unwind__flush_access(struct thread *thread)
    > +static void _unwind__flush_access(struct map_groups *mg)
    > {
    > if (!dwarf_callchain_users)
    > return;
    > - unw_flush_cache(thread->addr_space, 0, 0);
    > +
    > + unw_flush_cache(mg->addr_space, 0, 0);
    > }
    >
    > -static void _unwind__finish_access(struct thread *thread)
    > +static void _unwind__finish_access(struct map_groups *mg)
    > {
    > if (!dwarf_callchain_users)
    > return;
    > - unw_destroy_addr_space(thread->addr_space);
    > +
    > + unw_destroy_addr_space(mg->addr_space);
    > }
    >
    > static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
    > @@ -650,7 +653,6 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
    > {
    > u64 val;
    > unw_word_t ips[max_stack];
    > - unw_addr_space_t addr_space;
    > unw_cursor_t c;
    > int ret, i = 0;
    >
    > @@ -666,13 +668,15 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
    > * unwind itself.
    > */
    > if (max_stack - 1 > 0) {
    > + struct map_groups *mg;
    > +
    > WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
    > - addr_space = ui->thread->addr_space;
    >
    > - if (addr_space == NULL)
    > + mg = thread__get_map_groups(ui->thread, ui->sample->time);
    > + if (mg == NULL || mg->addr_space == NULL)
    > return -1;
    >
    > - ret = unw_init_remote(&c, addr_space, ui);
    > + ret = unw_init_remote(&c, mg->addr_space, ui);
    > if (ret)
    > display_error(ret);
    >
    > diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
    > index b029a5e9ae49..ce8408e460f2 100644
    > --- a/tools/perf/util/unwind-libunwind.c
    > +++ b/tools/perf/util/unwind-libunwind.c
    > @@ -18,12 +18,13 @@ static void unwind__register_ops(struct thread *thread,
    > int unwind__prepare_access(struct thread *thread, struct map *map,
    > bool *initialized)
    > {
    > + struct map_groups *mg = thread->mg;
    > const char *arch;
    > enum dso_type dso_type;
    > struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
    > int err;
    >
    > - if (thread->addr_space) {
    > + if (mg->addr_space) {
    > pr_debug("unwind: thread map already set, dso=%s\n",
    > map->dso->name);
    > if (initialized)
    > @@ -56,7 +57,7 @@ int unwind__prepare_access(struct thread *thread, struct map *map,
    > out_register:
    > unwind__register_ops(thread, ops);
    >
    > - err = thread->unwind_libunwind_ops->prepare_access(thread);
    > + err = thread->unwind_libunwind_ops->prepare_access(thread->mg);
    > if (initialized)
    > *initialized = err ? false : true;
    > return err;
    > @@ -65,13 +66,13 @@ int unwind__prepare_access(struct thread *thread, struct map *map,
    > void unwind__flush_access(struct thread *thread)
    > {
    > if (thread->unwind_libunwind_ops)
    > - thread->unwind_libunwind_ops->flush_access(thread);
    > + thread->unwind_libunwind_ops->flush_access(thread->mg);
    > }
    >
    > void unwind__finish_access(struct thread *thread)
    > {
    > if (thread->unwind_libunwind_ops)
    > - thread->unwind_libunwind_ops->finish_access(thread);
    > + thread->unwind_libunwind_ops->finish_access(thread->mg);
    > }
    >
    > int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
    > diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
    > index 8a44a1569a21..0f18a0858904 100644
    > --- a/tools/perf/util/unwind.h
    > +++ b/tools/perf/util/unwind.h
    > @@ -9,6 +9,7 @@ struct map;
    > struct perf_sample;
    > struct symbol;
    > struct thread;
    > +struct map_groups;
    >
    > struct unwind_entry {
    > struct map *map;
    > @@ -19,9 +20,9 @@ struct unwind_entry {
    > typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
    >
    > struct unwind_libunwind_ops {
    > - int (*prepare_access)(struct thread *thread);
    > - void (*flush_access)(struct thread *thread);
    > - void (*finish_access)(struct thread *thread);
    > + int (*prepare_access)(struct map_groups *mg);
    > + void (*flush_access)(struct map_groups *mg);
    > + void (*finish_access)(struct map_groups *mg);
    > int (*get_entries)(unwind_entry_cb_t cb, void *arg,
    > struct thread *thread,
    > struct perf_sample *data, int max_stack);
    > --
    > 2.17.1

    \
     
     \ /
      Last update: 2018-09-14 20:16    [W:3.483 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site