aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2016-04-07 03:11:12 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-04-08 08:58:02 -0400
commite583d70c54976f81855c7ca763b036bad399f4e0 (patch)
treec7bdea4441984b3a710f8921e60acef837910fec /tools/perf
parent7d6a7e782558323364bc0ae59f3523175c10b258 (diff)
perf tools: Add dedicated unwind addr_space member into thread struct
Milian reported issue with thread::priv, which was double booked by perf trace and DWARF unwind code. So using those together is impossible at the moment. Moving DWARF unwind private data into separate variable so perf trace can keep using thread::priv. Reported-and-Tested-by: Milian Wolff <milian.wolff@kdab.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Andreas Hollmann <hollmann@in.tum.de> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1460013073-18444-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/thread.h6
-rw-r--r--tools/perf/util/unwind-libunwind.c25
2 files changed, 15 insertions, 16 deletions
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index a0ac0317affb..e214207bb13a 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -9,6 +9,9 @@
9#include "symbol.h" 9#include "symbol.h"
10#include <strlist.h> 10#include <strlist.h>
11#include <intlist.h> 11#include <intlist.h>
12#ifdef HAVE_LIBUNWIND_SUPPORT
13#include <libunwind.h>
14#endif
12 15
13struct thread_stack; 16struct thread_stack;
14 17
@@ -32,6 +35,9 @@ struct thread {
32 35
33 void *priv; 36 void *priv;
34 struct thread_stack *ts; 37 struct thread_stack *ts;
38#ifdef HAVE_LIBUNWIND_SUPPORT
39 unw_addr_space_t addr_space;
40#endif
35}; 41};
36 42
37struct machine; 43struct machine;
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index ee7e372297e5..63687d3a344e 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -32,6 +32,7 @@
32#include "symbol.h" 32#include "symbol.h"
33#include "util.h" 33#include "util.h"
34#include "debug.h" 34#include "debug.h"
35#include "asm/bug.h"
35 36
36extern int 37extern int
37UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, 38UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
@@ -580,43 +581,33 @@ static unw_accessors_t accessors = {
580 581
581int unwind__prepare_access(struct thread *thread) 582int unwind__prepare_access(struct thread *thread)
582{ 583{
583 unw_addr_space_t addr_space;
584
585 if (callchain_param.record_mode != CALLCHAIN_DWARF) 584 if (callchain_param.record_mode != CALLCHAIN_DWARF)
586 return 0; 585 return 0;
587 586
588 addr_space = unw_create_addr_space(&accessors, 0); 587 thread->addr_space = unw_create_addr_space(&accessors, 0);
589 if (!addr_space) { 588 if (!thread->addr_space) {
590 pr_err("unwind: Can't create unwind address space.\n"); 589 pr_err("unwind: Can't create unwind address space.\n");
591 return -ENOMEM; 590 return -ENOMEM;
592 } 591 }
593 592
594 unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL); 593 unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
595 thread__set_priv(thread, addr_space);
596
597 return 0; 594 return 0;
598} 595}
599 596
600void unwind__flush_access(struct thread *thread) 597void unwind__flush_access(struct thread *thread)
601{ 598{
602 unw_addr_space_t addr_space;
603
604 if (callchain_param.record_mode != CALLCHAIN_DWARF) 599 if (callchain_param.record_mode != CALLCHAIN_DWARF)
605 return; 600 return;
606 601
607 addr_space = thread__priv(thread); 602 unw_flush_cache(thread->addr_space, 0, 0);
608 unw_flush_cache(addr_space, 0, 0);
609} 603}
610 604
611void unwind__finish_access(struct thread *thread) 605void unwind__finish_access(struct thread *thread)
612{ 606{
613 unw_addr_space_t addr_space;
614
615 if (callchain_param.record_mode != CALLCHAIN_DWARF) 607 if (callchain_param.record_mode != CALLCHAIN_DWARF)
616 return; 608 return;
617 609
618 addr_space = thread__priv(thread); 610 unw_destroy_addr_space(thread->addr_space);
619 unw_destroy_addr_space(addr_space);
620} 611}
621 612
622static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, 613static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
@@ -639,7 +630,9 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
639 * unwind itself. 630 * unwind itself.
640 */ 631 */
641 if (max_stack - 1 > 0) { 632 if (max_stack - 1 > 0) {
642 addr_space = thread__priv(ui->thread); 633 WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
634 addr_space = ui->thread->addr_space;
635
643 if (addr_space == NULL) 636 if (addr_space == NULL)
644 return -1; 637 return -1;
645 638