Merge tag 'renesas-boards-cleanups2-for-v3.19' of git://git.kernel.org/pub/scm/linux...
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / unwind-libunwind.c
index 92b56db5247193fb4c74f6d88cd5d49a542087ad..4d45c0dfe34347ef57527dd90f132e9067eb57e9 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/list.h>
 #include <libunwind.h>
 #include <libunwind-ptrace.h>
+#include "callchain.h"
 #include "thread.h"
 #include "session.h"
 #include "perf_regs.h"
@@ -525,12 +526,12 @@ static unw_accessors_t accessors = {
        .get_proc_name          = get_proc_name,
 };
 
-static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
-                      void *arg, int max_stack)
+int unwind__prepare_access(struct thread *thread)
 {
        unw_addr_space_t addr_space;
-       unw_cursor_t c;
-       int ret;
+
+       if (callchain_param.record_mode != CALLCHAIN_DWARF)
+               return 0;
 
        addr_space = unw_create_addr_space(&accessors, 0);
        if (!addr_space) {
@@ -538,6 +539,45 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
                return -ENOMEM;
        }
 
+       unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL);
+       thread__set_priv(thread, addr_space);
+
+       return 0;
+}
+
+void unwind__flush_access(struct thread *thread)
+{
+       unw_addr_space_t addr_space;
+
+       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)
+               return;
+
+       addr_space = thread__priv(thread);
+       unw_destroy_addr_space(addr_space);
+}
+
+static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
+                      void *arg, int max_stack)
+{
+       unw_addr_space_t addr_space;
+       unw_cursor_t c;
+       int ret;
+
+       addr_space = thread__priv(ui->thread);
+       if (addr_space == NULL)
+               return -1;
+
        ret = unw_init_remote(&c, addr_space, ui);
        if (ret)
                display_error(ret);
@@ -549,7 +589,6 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
                ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0;
        }
 
-       unw_destroy_addr_space(addr_space);
        return ret;
 }