linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL 00/24] perf/core improvements and fixes
@ 2016-06-07 20:04 Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 01/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private() Arnaldo Carvalho de Melo
                   ` (25 more replies)
  0 siblings, 26 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	Alexander Shishkin, Andi Kleen, David Ahern, Ekaterina Tumanova,
	He Kuang, Jiri Olsa, Josh Poimboeuf, Kan Liang, Masami Hiramatsu,
	Milian Wolff, Namhyung Kim, Pekka Enberg, Peter Zijlstra,
	pi3orama, Stephane Eranian, Sukadev Bhattiprolu, Taeung Song,
	Wang Nan, Zefan Li, Arnaldo Carvalho de Melo

Hi Ingo,

	Please consider pulling, this is on top of perf-core-for-mingo-20160606,

Thanks,

- Arnaldo

The following changes since commit 7db91f251056f90fec4121f028680ab3153a0f3c:

  perf config: Handle the error when config set is NULL at collect_config() (2016-06-06 17:43:19 -0300)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160607

for you to fetch changes up to 057fbfb25cde4a368418f3f720cdc31d48800c4d:

  perf callchain: Support aarch64 cross-platform (2016-06-07 15:13:35 -0300)

----------------------------------------------------------------
perf/core improvements and fixes:

User visible:

- Support cross unwinding, i.e. collecting '--call-graph dwarf' perf.data files
  in one machine and then doing analysis in another machine of a different
  hardware architecture. This enables, for instance, to do:

	perf record -a --call-graph dwarf

  on a x86-32 or aarch64 system and then do 'perf report' on it on a
  x86_64 workstation. (He Kuang)

- Fix crash in build_id_cache__kallsyms_path(), recent regression (Wang Nan)

Infrastructure:

- Make tools/lib/bpf use the IS_ERR return facility consistently and also stop
  using the _get_ term for non-reference count methods (Arnaldo Carvalho de Melo)

- 'perf config' refactorings (Taeung Song)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

----------------------------------------------------------------
Arnaldo Carvalho de Melo (7):
      tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private()
      tools lib bpf: Rename bpf_map__get_name() to bpf_map__name()
      tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def()
      tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd()
      tools lib bpf: Remove _get_ from non-refcount method names
      tools lib bpf: Make bpf_program__get_private() use IS_ERR()
      tools lib bpf: Rename set_private() to set_priv()

He Kuang (14):
      perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check
      perf unwind: Decouple thread->address_space on libunwind
      perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind
      perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map
      perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS
      perf unwind: Separate local/remote libunwind config
      perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c
      perf tools: Extract common API out of unwind-libunwind-local.c
      perf tools: Export normalize_arch() function
      perf unwind: Check the target platform before assigning unwind methods
      perf unwind: Change fixed name of libunwind__arch_reg_id to macro
      perf unwind: Introduce flag to separate local/remote unwind compilation
      perf callchain: Support x86 target platform
      perf callchain: Support aarch64 cross-platform

Taeung Song (2):
      perf config: Constructor should free its allocated memory when failing
      perf config: Use new perf_config_set__init() to initialize config set

Wang Nan (1):
      perf tools: Fix crash in build_id_cache__kallsyms_path()

 tools/lib/bpf/libbpf.c                        |  60 +--
 tools/lib/bpf/libbpf.h                        |  25 +-
 tools/perf/arch/arm/util/Build                |   2 +-
 tools/perf/arch/arm64/util/Build              |   2 +-
 tools/perf/arch/arm64/util/unwind-libunwind.c |   4 +-
 tools/perf/arch/common.c                      |   2 +-
 tools/perf/arch/common.h                      |   1 +
 tools/perf/arch/x86/util/Build                |   2 +-
 tools/perf/arch/x86/util/unwind-libunwind.c   |   6 +-
 tools/perf/config/Makefile                    |  52 +-
 tools/perf/util/Build                         |   3 +
 tools/perf/util/bpf-loader.c                  | 132 +++--
 tools/perf/util/build-id.c                    |  11 +-
 tools/perf/util/config.c                      |  51 +-
 tools/perf/util/libunwind/arm64.c             |  35 ++
 tools/perf/util/libunwind/x86_32.c            |  37 ++
 tools/perf/util/machine.c                     |  14 +-
 tools/perf/util/thread.c                      |  13 +-
 tools/perf/util/thread.h                      |   9 +-
 tools/perf/util/unwind-libunwind-local.c      | 697 ++++++++++++++++++++++++++
 tools/perf/util/unwind-libunwind.c            | 688 ++-----------------------
 tools/perf/util/unwind.h                      |  22 +-
 22 files changed, 1056 insertions(+), 812 deletions(-)
 create mode 100644 tools/perf/util/libunwind/arm64.c
 create mode 100644 tools/perf/util/libunwind/x86_32.c
 create mode 100644 tools/perf/util/unwind-libunwind-local.c

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 02/24] tools lib bpf: Rename bpf_map__get_name() to bpf_map__name() Arnaldo Carvalho de Melo
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

To try to, over time, consistently use the IS_ERR() interface instead of
using two return values, i.e. the integer return value for an error and
the pointer address to return the bpf_map->priv pointer.

Also rename it to bpf__priv(), to leave the "get" term for reference
counting.

Noticed while working on using BPF for collecting non-integer syscall
argument payloads (struct sockaddr in calls such as connect(), for
instance), where we need to use BPF maps and thus generalise
bpf__setup_stdout() to connect bpf_output events with maps in a bpf
proggie.

Acked-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-saypxyd6ptrct379jqgxx4bl@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       |  9 ++-------
 tools/lib/bpf/libbpf.h       |  2 +-
 tools/perf/util/bpf-loader.c | 23 +++++++++--------------
 3 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 7e543c3102d4..9bba1a907abe 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1351,14 +1351,9 @@ int bpf_map__set_private(struct bpf_map *map, void *priv,
 	return 0;
 }
 
-int bpf_map__get_private(struct bpf_map *map, void **ppriv)
+void *bpf_map__priv(struct bpf_map *map)
 {
-	if (!map)
-		return -EINVAL;
-
-	if (ppriv)
-		*ppriv = map->priv;
-	return 0;
+	return map ? map->priv : ERR_PTR(-EINVAL);
 }
 
 struct bpf_map *
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index a51594c7b518..916abf971249 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -187,6 +187,6 @@ const char *bpf_map__get_name(struct bpf_map *map);
 typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
 int bpf_map__set_private(struct bpf_map *map, void *priv,
 			 bpf_map_clear_priv_t clear_priv);
-int bpf_map__get_private(struct bpf_map *map, void **ppriv);
+void *bpf_map__priv(struct bpf_map *map);
 
 #endif
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 493307d1414c..e9a034e86b91 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -897,15 +897,13 @@ bpf_map_priv__clone(struct bpf_map_priv *priv)
 static int
 bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
 {
-	struct bpf_map_priv *priv;
+	struct bpf_map_priv *priv = bpf_map__priv(map);
 	const char *map_name;
-	int err;
 
 	map_name = bpf_map__get_name(map);
-	err = bpf_map__get_private(map, (void **)&priv);
-	if (err) {
+	if (IS_ERR(priv)) {
 		pr_debug("Failed to get private from map %s\n", map_name);
-		return err;
+		return PTR_ERR(priv);
 	}
 
 	if (!priv) {
@@ -1264,12 +1262,11 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 	const char *name;
 	struct bpf_map_op *op;
 	struct bpf_map_def def;
-	struct bpf_map_priv *priv;
+	struct bpf_map_priv *priv = bpf_map__priv(map);
 
 	name = bpf_map__get_name(map);
 
-	err = bpf_map__get_private(map, (void **)&priv);
-	if (err) {
+	if (IS_ERR(priv)) {
 		pr_debug("ERROR: failed to get private from map %s\n", name);
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
@@ -1489,10 +1486,9 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 	bool need_init = false;
 
 	bpf__for_each_stdout_map(map, obj, tmp) {
-		struct bpf_map_priv *priv;
+		struct bpf_map_priv *priv = bpf_map__priv(map);
 
-		err = bpf_map__get_private(map, (void **)&priv);
-		if (err)
+		if (IS_ERR(priv))
 			return -BPF_LOADER_ERRNO__INTERNAL;
 
 		/*
@@ -1520,10 +1516,9 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 	}
 
 	bpf__for_each_stdout_map(map, obj, tmp) {
-		struct bpf_map_priv *priv;
+		struct bpf_map_priv *priv = bpf_map__priv(map);
 
-		err = bpf_map__get_private(map, (void **)&priv);
-		if (err)
+		if (IS_ERR(priv))
 			return -BPF_LOADER_ERRNO__INTERNAL;
 		if (priv)
 			continue;
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/24] tools lib bpf: Rename bpf_map__get_name() to bpf_map__name()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 01/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 03/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def() Arnaldo Carvalho de Melo
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

For consistency, leaving "get" for reference counting.

Acked-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-crnflv84ejyhpba933ec71gs@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       |  6 ++----
 tools/lib/bpf/libbpf.h       |  2 +-
 tools/perf/util/bpf-loader.c | 18 ++++++------------
 3 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 9bba1a907abe..4dc617befd13 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1328,11 +1328,9 @@ int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef)
 	return 0;
 }
 
-const char *bpf_map__get_name(struct bpf_map *map)
+const char *bpf_map__name(struct bpf_map *map)
 {
-	if (!map)
-		return NULL;
-	return map->name;
+	return map ? map->name : NULL;
 }
 
 int bpf_map__set_private(struct bpf_map *map, void *priv,
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 916abf971249..f8fbba4ccef3 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -182,7 +182,7 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
 
 int bpf_map__get_fd(struct bpf_map *map);
 int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef);
-const char *bpf_map__get_name(struct bpf_map *map);
+const char *bpf_map__name(struct bpf_map *map);
 
 typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
 int bpf_map__set_private(struct bpf_map *map, void *priv,
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index e9a034e86b91..c819eb8ba145 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -897,10 +897,9 @@ bpf_map_priv__clone(struct bpf_map_priv *priv)
 static int
 bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
 {
+	const char *map_name = bpf_map__name(map);
 	struct bpf_map_priv *priv = bpf_map__priv(map);
-	const char *map_name;
 
-	map_name = bpf_map__get_name(map);
 	if (IS_ERR(priv)) {
 		pr_debug("Failed to get private from map %s\n", map_name);
 		return PTR_ERR(priv);
@@ -948,11 +947,9 @@ __bpf_map__config_value(struct bpf_map *map,
 {
 	struct bpf_map_def def;
 	struct bpf_map_op *op;
-	const char *map_name;
+	const char *map_name = bpf_map__name(map);
 	int err;
 
-	map_name = bpf_map__get_name(map);
-
 	err = bpf_map__get_def(map, &def);
 	if (err) {
 		pr_debug("Unable to get map definition from '%s'\n",
@@ -1014,10 +1011,9 @@ __bpf_map__config_event(struct bpf_map *map,
 	struct perf_evsel *evsel;
 	struct bpf_map_def def;
 	struct bpf_map_op *op;
-	const char *map_name;
+	const char *map_name = bpf_map__name(map);
 	int err;
 
-	map_name = bpf_map__get_name(map);
 	evsel = perf_evlist__find_evsel_by_str(evlist, term->val.str);
 	if (!evsel) {
 		pr_debug("Event (for '%s') '%s' doesn't exist\n",
@@ -1259,13 +1255,11 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 			   void *arg)
 {
 	int err, map_fd;
-	const char *name;
 	struct bpf_map_op *op;
 	struct bpf_map_def def;
+	const char *name = bpf_map__name(map);
 	struct bpf_map_priv *priv = bpf_map__priv(map);
 
-	name = bpf_map__get_name(map);
-
 	if (IS_ERR(priv)) {
 		pr_debug("ERROR: failed to get private from map %s\n", name);
 		return -BPF_LOADER_ERRNO__INTERNAL;
@@ -1472,9 +1466,9 @@ int bpf__apply_obj_config(void)
 
 #define bpf__for_each_stdout_map(pos, obj, objtmp)	\
 	bpf__for_each_map(pos, obj, objtmp) 		\
-		if (bpf_map__get_name(pos) && 		\
+		if (bpf_map__name(pos) && 		\
 			(strcmp("__bpf_stdout__", 	\
-				bpf_map__get_name(pos)) == 0))
+				bpf_map__name(pos)) == 0))
 
 int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 {
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 01/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private() Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 02/24] tools lib bpf: Rename bpf_map__get_name() to bpf_map__name() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 04/24] tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd() Arnaldo Carvalho de Melo
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

And for consistency, rename it to bpf_map__def(), leaving "get" for
reference counting.

Also make it return a const pointer, as suggested by Wang.

Acked-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-mer00xqkiho0ymg66b5i9luw@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       |  8 ++-----
 tools/lib/bpf/libbpf.h       |  2 +-
 tools/perf/util/bpf-loader.c | 52 ++++++++++++++++++++------------------------
 3 files changed, 27 insertions(+), 35 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 4dc617befd13..215be67f038b 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1319,13 +1319,9 @@ int bpf_map__get_fd(struct bpf_map *map)
 	return map->fd;
 }
 
-int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef)
+const struct bpf_map_def *bpf_map__def(struct bpf_map *map)
 {
-	if (!map || !pdef)
-		return -EINVAL;
-
-	*pdef = map->def;
-	return 0;
+	return map ? &map->def : ERR_PTR(-EINVAL);
 }
 
 const char *bpf_map__name(struct bpf_map *map)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index f8fbba4ccef3..bad5bac58db4 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -181,7 +181,7 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
 	     (pos) = bpf_map__next((pos), (obj)))
 
 int bpf_map__get_fd(struct bpf_map *map);
-int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef);
+const struct bpf_map_def *bpf_map__def(struct bpf_map *map);
 const char *bpf_map__name(struct bpf_map *map);
 
 typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index c819eb8ba145..73c1e7cf8760 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -945,28 +945,26 @@ static int
 __bpf_map__config_value(struct bpf_map *map,
 			struct parse_events_term *term)
 {
-	struct bpf_map_def def;
 	struct bpf_map_op *op;
 	const char *map_name = bpf_map__name(map);
-	int err;
+	const struct bpf_map_def *def = bpf_map__def(map);
 
-	err = bpf_map__get_def(map, &def);
-	if (err) {
+	if (IS_ERR(def)) {
 		pr_debug("Unable to get map definition from '%s'\n",
 			 map_name);
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
 
-	if (def.type != BPF_MAP_TYPE_ARRAY) {
+	if (def->type != BPF_MAP_TYPE_ARRAY) {
 		pr_debug("Map %s type is not BPF_MAP_TYPE_ARRAY\n",
 			 map_name);
 		return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
 	}
-	if (def.key_size < sizeof(unsigned int)) {
+	if (def->key_size < sizeof(unsigned int)) {
 		pr_debug("Map %s has incorrect key size\n", map_name);
 		return -BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE;
 	}
-	switch (def.value_size) {
+	switch (def->value_size) {
 	case 1:
 	case 2:
 	case 4:
@@ -1009,10 +1007,9 @@ __bpf_map__config_event(struct bpf_map *map,
 			struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
-	struct bpf_map_def def;
+	const struct bpf_map_def *def;
 	struct bpf_map_op *op;
 	const char *map_name = bpf_map__name(map);
-	int err;
 
 	evsel = perf_evlist__find_evsel_by_str(evlist, term->val.str);
 	if (!evsel) {
@@ -1021,18 +1018,18 @@ __bpf_map__config_event(struct bpf_map *map,
 		return -BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT;
 	}
 
-	err = bpf_map__get_def(map, &def);
-	if (err) {
+	def = bpf_map__def(map);
+	if (IS_ERR(def)) {
 		pr_debug("Unable to get map definition from '%s'\n",
 			 map_name);
-		return err;
+		return PTR_ERR(def);
 	}
 
 	/*
 	 * No need to check key_size and value_size:
 	 * kernel has already checked them.
 	 */
-	if (def.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {
+	if (def->type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {
 		pr_debug("Map %s type is not BPF_MAP_TYPE_PERF_EVENT_ARRAY\n",
 			 map_name);
 		return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
@@ -1081,9 +1078,8 @@ config_map_indices_range_check(struct parse_events_term *term,
 			       const char *map_name)
 {
 	struct parse_events_array *array = &term->array;
-	struct bpf_map_def def;
+	const struct bpf_map_def *def;
 	unsigned int i;
-	int err;
 
 	if (!array->nr_ranges)
 		return 0;
@@ -1093,8 +1089,8 @@ config_map_indices_range_check(struct parse_events_term *term,
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
 
-	err = bpf_map__get_def(map, &def);
-	if (err) {
+	def = bpf_map__def(map);
+	if (IS_ERR(def)) {
 		pr_debug("ERROR: Unable to get map definition from '%s'\n",
 			 map_name);
 		return -BPF_LOADER_ERRNO__INTERNAL;
@@ -1105,7 +1101,7 @@ config_map_indices_range_check(struct parse_events_term *term,
 		size_t length = array->ranges[i].length;
 		unsigned int idx = start + length - 1;
 
-		if (idx >= def.max_entries) {
+		if (idx >= def->max_entries) {
 			pr_debug("ERROR: index %d too large\n", idx);
 			return -BPF_LOADER_ERRNO__OBJCONF_MAP_IDX2BIG;
 		}
@@ -1198,14 +1194,14 @@ out:
 }
 
 typedef int (*map_config_func_t)(const char *name, int map_fd,
-				 struct bpf_map_def *pdef,
+				 const struct bpf_map_def *pdef,
 				 struct bpf_map_op *op,
 				 void *pkey, void *arg);
 
 static int
 foreach_key_array_all(map_config_func_t func,
 		      void *arg, const char *name,
-		      int map_fd, struct bpf_map_def *pdef,
+		      int map_fd, const struct bpf_map_def *pdef,
 		      struct bpf_map_op *op)
 {
 	unsigned int i;
@@ -1225,7 +1221,7 @@ foreach_key_array_all(map_config_func_t func,
 static int
 foreach_key_array_ranges(map_config_func_t func, void *arg,
 			 const char *name, int map_fd,
-			 struct bpf_map_def *pdef,
+			 const struct bpf_map_def *pdef,
 			 struct bpf_map_op *op)
 {
 	unsigned int i, j;
@@ -1256,7 +1252,7 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 {
 	int err, map_fd;
 	struct bpf_map_op *op;
-	struct bpf_map_def def;
+	const struct bpf_map_def *def;
 	const char *name = bpf_map__name(map);
 	struct bpf_map_priv *priv = bpf_map__priv(map);
 
@@ -1269,8 +1265,8 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 		return 0;
 	}
 
-	err = bpf_map__get_def(map, &def);
-	if (err) {
+	def = bpf_map__def(map);
+	if (IS_ERR(def)) {
 		pr_debug("ERROR: failed to get definition from map %s\n", name);
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
@@ -1281,17 +1277,17 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 	}
 
 	list_for_each_entry(op, &priv->ops_list, list) {
-		switch (def.type) {
+		switch (def->type) {
 		case BPF_MAP_TYPE_ARRAY:
 		case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
 			switch (op->key_type) {
 			case BPF_MAP_KEY_ALL:
 				err = foreach_key_array_all(func, arg, name,
-							    map_fd, &def, op);
+							    map_fd, def, op);
 				break;
 			case BPF_MAP_KEY_RANGES:
 				err = foreach_key_array_ranges(func, arg, name,
-							       map_fd, &def,
+							       map_fd, def,
 							       op);
 				break;
 			default:
@@ -1401,7 +1397,7 @@ apply_config_evsel_for_key(const char *name, int map_fd, void *pkey,
 
 static int
 apply_obj_config_map_for_key(const char *name, int map_fd,
-			     struct bpf_map_def *pdef __maybe_unused,
+			     const struct bpf_map_def *pdef,
 			     struct bpf_map_op *op,
 			     void *pkey, void *arg __maybe_unused)
 {
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/24] tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (2 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 03/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 05/24] tools lib bpf: Remove _get_ from non-refcount method names Arnaldo Carvalho de Melo
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

For consistency, leaving "get" for reference counting.

Acked-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-msy8sxfz9th6gl2xjeci2btm@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       | 7 ++-----
 tools/lib/bpf/libbpf.h       | 2 +-
 tools/perf/util/bpf-loader.c | 2 +-
 3 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 215be67f038b..57924db2d16f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1311,12 +1311,9 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n)
 	return fd;
 }
 
-int bpf_map__get_fd(struct bpf_map *map)
+int bpf_map__fd(struct bpf_map *map)
 {
-	if (!map)
-		return -EINVAL;
-
-	return map->fd;
+	return map ? map->fd : -EINVAL;
 }
 
 const struct bpf_map_def *bpf_map__def(struct bpf_map *map)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index bad5bac58db4..cb838d0ea753 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -180,7 +180,7 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
 	     (pos) != NULL;				\
 	     (pos) = bpf_map__next((pos), (obj)))
 
-int bpf_map__get_fd(struct bpf_map *map);
+int bpf_map__fd(struct bpf_map *map);
 const struct bpf_map_def *bpf_map__def(struct bpf_map *map);
 const char *bpf_map__name(struct bpf_map *map);
 
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 73c1e7cf8760..12e6ef4c2f9e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -1270,7 +1270,7 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 		pr_debug("ERROR: failed to get definition from map %s\n", name);
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
-	map_fd = bpf_map__get_fd(map);
+	map_fd = bpf_map__fd(map);
 	if (map_fd < 0) {
 		pr_debug("ERROR: failed to get fd from map %s\n", name);
 		return map_fd;
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/24] tools lib bpf: Remove _get_ from non-refcount method names
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (3 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 04/24] tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 06/24] tools lib bpf: Make bpf_program__get_private() use IS_ERR() Arnaldo Carvalho de Melo
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

The use of this term is not warranted here, we use it in the kernel
sources and in tools/ for refcounting, so, for consistency, rename them.

Acked-bu: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-4ya1ot2e2fkrz48ws9ebiofs@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       | 16 +++++-----------
 tools/lib/bpf/libbpf.h       |  6 +++---
 tools/perf/util/bpf-loader.c |  4 ++--
 3 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 57924db2d16f..0412182fb365 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1186,20 +1186,14 @@ bpf_object__next(struct bpf_object *prev)
 	return next;
 }
 
-const char *
-bpf_object__get_name(struct bpf_object *obj)
+const char *bpf_object__name(struct bpf_object *obj)
 {
-	if (!obj)
-		return ERR_PTR(-EINVAL);
-	return obj->path;
+	return obj ? obj->path : ERR_PTR(-EINVAL);
 }
 
-unsigned int
-bpf_object__get_kversion(struct bpf_object *obj)
+unsigned int bpf_object__kversion(struct bpf_object *obj)
 {
-	if (!obj)
-		return 0;
-	return obj->kern_version;
+	return obj ? obj->kern_version : 0;
 }
 
 struct bpf_program *
@@ -1375,7 +1369,7 @@ bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
 }
 
 struct bpf_map *
-bpf_object__get_map_by_name(struct bpf_object *obj, const char *name)
+bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
 {
 	struct bpf_map *pos;
 
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index cb838d0ea753..ea65775e8302 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -55,8 +55,8 @@ void bpf_object__close(struct bpf_object *object);
 /* Load/unload object into/from kernel */
 int bpf_object__load(struct bpf_object *obj);
 int bpf_object__unload(struct bpf_object *obj);
-const char *bpf_object__get_name(struct bpf_object *obj);
-unsigned int bpf_object__get_kversion(struct bpf_object *obj);
+const char *bpf_object__name(struct bpf_object *obj);
+unsigned int bpf_object__kversion(struct bpf_object *obj);
 
 struct bpf_object *bpf_object__next(struct bpf_object *prev);
 #define bpf_object__for_each_safe(pos, tmp)			\
@@ -171,7 +171,7 @@ struct bpf_map_def {
  */
 struct bpf_map;
 struct bpf_map *
-bpf_object__get_map_by_name(struct bpf_object *obj, const char *name);
+bpf_object__find_map_by_name(struct bpf_object *obj, const char *name);
 
 struct bpf_map *
 bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 12e6ef4c2f9e..c19010e6cefb 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -1137,7 +1137,7 @@ bpf__obj_config_map(struct bpf_object *obj,
 		goto out;
 	}
 
-	map = bpf_object__get_map_by_name(obj, map_name);
+	map = bpf_object__find_map_by_name(obj, map_name);
 	if (!map) {
 		pr_debug("ERROR: Map %s doesn't exist\n", map_name);
 		err = -BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST;
@@ -1662,7 +1662,7 @@ int bpf__strerror_load(struct bpf_object *obj,
 {
 	bpf__strerror_head(err, buf, size);
 	case LIBBPF_ERRNO__KVER: {
-		unsigned int obj_kver = bpf_object__get_kversion(obj);
+		unsigned int obj_kver = bpf_object__kversion(obj);
 		unsigned int real_kver;
 
 		if (fetch_kernel_version(&real_kver, NULL, 0)) {
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/24] tools lib bpf: Make bpf_program__get_private() use IS_ERR()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (4 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 05/24] tools lib bpf: Remove _get_ from non-refcount method names Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 07/24] tools lib bpf: Rename set_private() to set_priv() Arnaldo Carvalho de Melo
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

For consistency with bpf_map__priv() and elsewhere.

Acked-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-x17nk5mrazkf45z0l0ahlmo8@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       |  5 ++---
 tools/lib/bpf/libbpf.h       |  3 +--
 tools/perf/util/bpf-loader.c | 27 ++++++++++++---------------
 3 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 0412182fb365..7eb7fb26e999 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1230,10 +1230,9 @@ int bpf_program__set_private(struct bpf_program *prog,
 	return 0;
 }
 
-int bpf_program__get_private(struct bpf_program *prog, void **ppriv)
+void *bpf_program__priv(struct bpf_program *prog)
 {
-	*ppriv = prog->priv;
-	return 0;
+	return prog ? prog->priv : ERR_PTR(-EINVAL);
 }
 
 const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index ea65775e8302..372cecbde207 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -81,8 +81,7 @@ typedef void (*bpf_program_clear_priv_t)(struct bpf_program *,
 int bpf_program__set_private(struct bpf_program *prog, void *priv,
 			     bpf_program_clear_priv_t clear_priv);
 
-int bpf_program__get_private(struct bpf_program *prog,
-			     void **ppriv);
+void *bpf_program__priv(struct bpf_program *prog);
 
 const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
 
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index c19010e6cefb..1907d5313960 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -380,15 +380,14 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
 		     struct bpf_insn *orig_insns, int orig_insns_cnt,
 		     struct bpf_prog_prep_result *res)
 {
+	struct bpf_prog_priv *priv = bpf_program__priv(prog);
 	struct probe_trace_event *tev;
 	struct perf_probe_event *pev;
-	struct bpf_prog_priv *priv;
 	struct bpf_insn *buf;
 	size_t prologue_cnt = 0;
 	int i, err;
 
-	err = bpf_program__get_private(prog, (void **)&priv);
-	if (err || !priv)
+	if (IS_ERR(priv) || !priv)
 		goto errout;
 
 	pev = &priv->pev;
@@ -535,13 +534,12 @@ static int map_prologue(struct perf_probe_event *pev, int *mapping,
 
 static int hook_load_preprocessor(struct bpf_program *prog)
 {
+	struct bpf_prog_priv *priv = bpf_program__priv(prog);
 	struct perf_probe_event *pev;
-	struct bpf_prog_priv *priv;
 	bool need_prologue = false;
 	int err, i;
 
-	err = bpf_program__get_private(prog, (void **)&priv);
-	if (err || !priv) {
+	if (IS_ERR(priv) || !priv) {
 		pr_debug("Internal error when hook preprocessor\n");
 		return -BPF_LOADER_ERRNO__INTERNAL;
 	}
@@ -607,9 +605,11 @@ int bpf__probe(struct bpf_object *obj)
 		if (err)
 			goto out;
 
-		err = bpf_program__get_private(prog, (void **)&priv);
-		if (err || !priv)
+		priv = bpf_program__priv(prog);
+		if (IS_ERR(priv) || !priv) {
+			err = PTR_ERR(priv);
 			goto out;
+		}
 		pev = &priv->pev;
 
 		err = convert_perf_probe_events(pev, 1);
@@ -645,13 +645,12 @@ int bpf__unprobe(struct bpf_object *obj)
 {
 	int err, ret = 0;
 	struct bpf_program *prog;
-	struct bpf_prog_priv *priv;
 
 	bpf_object__for_each_program(prog, obj) {
+		struct bpf_prog_priv *priv = bpf_program__priv(prog);
 		int i;
 
-		err = bpf_program__get_private(prog, (void **)&priv);
-		if (err || !priv)
+		if (IS_ERR(priv) || !priv)
 			continue;
 
 		for (i = 0; i < priv->pev.ntevs; i++) {
@@ -702,14 +701,12 @@ int bpf__foreach_tev(struct bpf_object *obj,
 	int err;
 
 	bpf_object__for_each_program(prog, obj) {
+		struct bpf_prog_priv *priv = bpf_program__priv(prog);
 		struct probe_trace_event *tev;
 		struct perf_probe_event *pev;
-		struct bpf_prog_priv *priv;
 		int i, fd;
 
-		err = bpf_program__get_private(prog,
-				(void **)&priv);
-		if (err || !priv) {
+		if (IS_ERR(priv) || !priv) {
 			pr_debug("bpf: failed to get private field\n");
 			return -BPF_LOADER_ERRNO__INTERNAL;
 		}
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/24] tools lib bpf: Rename set_private() to set_priv()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (5 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 06/24] tools lib bpf: Make bpf_program__get_private() use IS_ERR() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 08/24] perf tools: Fix crash in build_id_cache__kallsyms_path() Arnaldo Carvalho de Melo
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim

From: Arnaldo Carvalho de Melo <acme@redhat.com>

For consistency with class__priv() elsewhere, and with the callback
typedef for clearing those areas (e.g. bpf_map_clear_priv_t).

Acked-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-rnbiyv27ohw8xppsgx0el3xb@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c       | 9 ++++-----
 tools/lib/bpf/libbpf.h       | 8 ++++----
 tools/perf/util/bpf-loader.c | 6 +++---
 3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 7eb7fb26e999..462e526a4465 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1218,9 +1218,8 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
 	return &obj->programs[idx];
 }
 
-int bpf_program__set_private(struct bpf_program *prog,
-			     void *priv,
-			     bpf_program_clear_priv_t clear_priv)
+int bpf_program__set_priv(struct bpf_program *prog, void *priv,
+			  bpf_program_clear_priv_t clear_priv)
 {
 	if (prog->priv && prog->clear_priv)
 		prog->clear_priv(prog, prog->priv);
@@ -1319,8 +1318,8 @@ const char *bpf_map__name(struct bpf_map *map)
 	return map ? map->name : NULL;
 }
 
-int bpf_map__set_private(struct bpf_map *map, void *priv,
-			 bpf_map_clear_priv_t clear_priv)
+int bpf_map__set_priv(struct bpf_map *map, void *priv,
+		     bpf_map_clear_priv_t clear_priv)
 {
 	if (!map)
 		return -EINVAL;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 372cecbde207..722f46b2d553 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -78,8 +78,8 @@ struct bpf_program *bpf_program__next(struct bpf_program *prog,
 typedef void (*bpf_program_clear_priv_t)(struct bpf_program *,
 					 void *);
 
-int bpf_program__set_private(struct bpf_program *prog, void *priv,
-			     bpf_program_clear_priv_t clear_priv);
+int bpf_program__set_priv(struct bpf_program *prog, void *priv,
+			  bpf_program_clear_priv_t clear_priv);
 
 void *bpf_program__priv(struct bpf_program *prog);
 
@@ -184,8 +184,8 @@ const struct bpf_map_def *bpf_map__def(struct bpf_map *map);
 const char *bpf_map__name(struct bpf_map *map);
 
 typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
-int bpf_map__set_private(struct bpf_map *map, void *priv,
-			 bpf_map_clear_priv_t clear_priv);
+int bpf_map__set_priv(struct bpf_map *map, void *priv,
+		      bpf_map_clear_priv_t clear_priv);
 void *bpf_map__priv(struct bpf_map *map);
 
 #endif
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 1907d5313960..dcc8845881ae 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -339,7 +339,7 @@ config_bpf_program(struct bpf_program *prog)
 	}
 	pr_debug("bpf: config '%s' is ok\n", config_str);
 
-	err = bpf_program__set_private(prog, priv, clear_prog_priv);
+	err = bpf_program__set_priv(prog, priv, clear_prog_priv);
 	if (err) {
 		pr_debug("Failed to set priv for program '%s'\n", config_str);
 		goto errout;
@@ -910,7 +910,7 @@ bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
 		}
 		INIT_LIST_HEAD(&priv->ops_list);
 
-		if (bpf_map__set_private(map, priv, bpf_map_priv__clear)) {
+		if (bpf_map__set_priv(map, priv, bpf_map_priv__clear)) {
 			free(priv);
 			return -BPF_LOADER_ERRNO__INTERNAL;
 		}
@@ -1515,7 +1515,7 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 			if (!priv)
 				return -ENOMEM;
 
-			err = bpf_map__set_private(map, priv, bpf_map_priv__clear);
+			err = bpf_map__set_priv(map, priv, bpf_map_priv__clear);
 			if (err) {
 				bpf_map_priv__clear(map, priv);
 				return err;
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/24] perf tools: Fix crash in build_id_cache__kallsyms_path()
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (6 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 07/24] tools lib bpf: Rename set_private() to set_priv() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 09/24] perf config: Constructor should free its allocated memory when failing Arnaldo Carvalho de Melo
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Wang Nan, Masami Hiramatsu, Zefan Li, pi3orama,
	Arnaldo Carvalho de Melo

From: Wang Nan <wangnan0@huawei.com>

build_id_cache__kallsyms_path() accepts a string buffer but also allocs
a buffer using asnprintf. Unfortunately, the its only user passes it a
stack-allocated buffer. Freeing it causes crashes like this:

  $ perf script
  *** Error in `/home/wangnan/perf': free(): invalid pointer: 0x00007fffffff9630 ***
  ======= Backtrace: =========
  lib64/libc.so.6(+0x6eeef)[0x7ffff5dbaeef]
  lib64/libc.so.6(+0x78cae)[0x7ffff5dc4cae]
  lib64/libc.so.6(+0x79987)[0x7ffff5dc5987]
  /home/w00229757/perf(build_id_cache__kallsyms_path+0x6b)[0x49681b]
  /home/w00229757/perf[0x4bdd40]
  /home/w00229757/perf(dso__load+0xa3a)[0x4c048a]
  /home/w00229757/perf(map__load+0x6f)[0x4d561f]
  /home/w00229757/perf(thread__find_addr_map+0x235)[0x49e935]
  /home/w00229757/perf(machine__resolve+0x7d)[0x49ec6d]
  /home/w00229757/perf[0x4555a8]
  /home/w00229757/perf[0x4d9507]
  /home/w00229757/perf[0x4d9e80]
  /home/w00229757/perf(ordered_events__flush+0x354)[0x4dd444]
  /home/w00229757/perf(perf_session__process_events+0x3d0)[0x4dc140]
  /home/w00229757/perf(cmd_script+0x12b0)[0x4592e0]
  /home/w00229757/perf[0x4911f1]
  /home/w00229757/perf(main+0x68f)[0x4352ef]
  /lib64/libc.so.6(__libc_start_main+0xf5)[0x7ffff5d6dbd5]
  /home/w00229757/perf[0x435415]
  ======= Memory map: ========

This patch simplifies build_id_cache__kallsyms_path(), not even
considering allocating a string buffer, so never frees anything. Its
caller should manage memory allocation.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Fixes: 01412261d994 ("perf buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid")
Link: http://lkml.kernel.org/r/1465271678-7392-1-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/build-id.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 67f986c8c378..20aef90bf194 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -147,20 +147,17 @@ static int asnprintf(char **strp, size_t size, const char *fmt, ...)
 char *build_id_cache__kallsyms_path(const char *sbuild_id, char *bf,
 				    size_t size)
 {
-	bool is_alloc = !!bf;
 	bool retry_old = true;
 
-	asnprintf(&bf, size, "%s/%s/%s/kallsyms",
-		  buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
+	snprintf(bf, size, "%s/%s/%s/kallsyms",
+		 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
 retry:
 	if (!access(bf, F_OK))
 		return bf;
-	if (is_alloc)
-		free(bf);
 	if (retry_old) {
 		/* Try old style kallsyms cache */
-		asnprintf(&bf, size, "%s/%s/%s",
-			  buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
+		snprintf(bf, size, "%s/%s/%s",
+			 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
 		retry_old = false;
 		goto retry;
 	}
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/24] perf config: Constructor should free its allocated memory when failing
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (7 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 08/24] perf tools: Fix crash in build_id_cache__kallsyms_path() Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 10/24] perf config: Use new perf_config_set__init() to initialize config set Arnaldo Carvalho de Melo
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Taeung Song, Alexander Shishkin, Jiri Olsa,
	Masami Hiramatsu, Namhyung Kim, Peter Zijlstra,
	Arnaldo Carvalho de Melo

From: Taeung Song <treeze.taeung@gmail.com>

Because of die() at perf_parse_file() a config set was freed in
collect_config(), if failed.  But it is natural to free a config set
after collect_config() is done when some problems happened.

So, in case of failure, lastly free a config set at perf_config_set__new()
instead of freeing the config set in collect_config().

Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1465291577-20973-2-git-send-email-treeze.taeung@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/config.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index c73f1c4d1ca9..e086f593a2aa 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -643,7 +643,6 @@ static int collect_config(const char *var, const char *value,
 
 out_free:
 	free(key);
-	perf_config_set__delete(set);
 	return -1;
 }
 
@@ -653,7 +652,10 @@ struct perf_config_set *perf_config_set__new(void)
 
 	if (set) {
 		INIT_LIST_HEAD(&set->sections);
-		perf_config(collect_config, set);
+		if (perf_config(collect_config, set) < 0) {
+			perf_config_set__delete(set);
+			set = NULL;
+		}
 	}
 
 	return set;
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/24] perf config: Use new perf_config_set__init() to initialize config set
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (8 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 09/24] perf config: Constructor should free its allocated memory when failing Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 11/24] perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check Arnaldo Carvalho de Melo
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Taeung Song, Alexander Shishkin, Jiri Olsa,
	Masami Hiramatsu, Namhyung Kim, Peter Zijlstra,
	Arnaldo Carvalho de Melo

From: Taeung Song <treeze.taeung@gmail.com>

Instead of perf_config(), this function initializes config set by
reading various files: user config ~/.perfconfig and system config
$(sysconfdir)/perfconfig).

If there are the same config variable in both user and system config
files, user config has higher priority than system config.

Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1465291577-20973-3-git-send-email-treeze.taeung@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/config.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index e086f593a2aa..8749eca3055f 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -646,13 +646,58 @@ out_free:
 	return -1;
 }
 
+static int perf_config_set__init(struct perf_config_set *set)
+{
+	int ret = -1;
+	const char *home = NULL;
+
+	/* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
+	if (config_exclusive_filename)
+		return perf_config_from_file(collect_config, config_exclusive_filename, set);
+	if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
+		if (perf_config_from_file(collect_config, perf_etc_perfconfig(), set) < 0)
+			goto out;
+	}
+
+	home = getenv("HOME");
+	if (perf_config_global() && home) {
+		char *user_config = strdup(mkpath("%s/.perfconfig", home));
+		struct stat st;
+
+		if (user_config == NULL) {
+			warning("Not enough memory to process %s/.perfconfig, "
+				"ignoring it.", home);
+			goto out;
+		}
+
+		if (stat(user_config, &st) < 0)
+			goto out_free;
+
+		if (st.st_uid && (st.st_uid != geteuid())) {
+			warning("File %s not owned by current user or root, "
+				"ignoring it.", user_config);
+			goto out_free;
+		}
+
+		if (!st.st_size)
+			goto out_free;
+
+		ret = perf_config_from_file(collect_config, user_config, set);
+
+out_free:
+		free(user_config);
+	}
+out:
+	return ret;
+}
+
 struct perf_config_set *perf_config_set__new(void)
 {
 	struct perf_config_set *set = zalloc(sizeof(*set));
 
 	if (set) {
 		INIT_LIST_HEAD(&set->sections);
-		if (perf_config(collect_config, set) < 0) {
+		if (perf_config_set__init(set) < 0) {
 			perf_config_set__delete(set);
 			set = NULL;
 		}
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 11/24] perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (9 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 10/24] perf config: Use new perf_config_set__init() to initialize config set Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 12/24] perf unwind: Decouple thread->address_space on libunwind Arnaldo Carvalho de Melo
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Pass LIBUNWIND_DIR to feature check flags for remote libunwind
tests. So perf can be able to detect remote libunwind libraries from
arbitrary directory.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-2-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/config/Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 1e46277286c2..6f9f566a757c 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -67,9 +67,18 @@ endif
 #
 #   make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
 #
+
+libunwind_arch_set_flags = $(eval $(libunwind_arch_set_flags_code))
+define libunwind_arch_set_flags_code
+  FEATURE_CHECK_CFLAGS-libunwind-$(1)  = -I$(LIBUNWIND_DIR)/include
+  FEATURE_CHECK_LDFLAGS-libunwind-$(1) = -L$(LIBUNWIND_DIR)/lib
+endef
+
 ifdef LIBUNWIND_DIR
   LIBUNWIND_CFLAGS  = -I$(LIBUNWIND_DIR)/include
   LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib
+  LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64
+  $(foreach libunwind_arch,$(LIBUNWIND_ARCHS),$(call libunwind_arch_set_flags,$(libunwind_arch)))
 endif
 LIBUNWIND_LDFLAGS += $(LIBUNWIND_LIBS)
 
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 12/24] perf unwind: Decouple thread->address_space on libunwind
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (10 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 11/24] perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 13/24] perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind Arnaldo Carvalho de Melo
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Currently, the type of thread->addr_space is unw_addr_space_t, which is
a pointer defined in libunwind headers. For local libunwind, we can
simple include "libunwind.h", but for remote libunwind, the header file
is depends on the target libunwind platform. This patch uses 'void *'
instead to decouple the dependence on libunwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-3-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/thread.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 08fcb14cf637..4c9f0aa11f1f 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -9,9 +9,6 @@
 #include "symbol.h"
 #include <strlist.h>
 #include <intlist.h>
-#ifdef HAVE_LIBUNWIND_SUPPORT
-#include <libunwind.h>
-#endif
 
 struct thread_stack;
 
@@ -36,7 +33,7 @@ struct thread {
 	void			*priv;
 	struct thread_stack	*ts;
 #ifdef HAVE_LIBUNWIND_SUPPORT
-	unw_addr_space_t	addr_space;
+	void			*addr_space;
 #endif
 };
 
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 13/24] perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (11 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 12/24] perf unwind: Decouple thread->address_space on libunwind Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 14/24] perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map Arnaldo Carvalho de Melo
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Currently, libunwind operations are fixed, and they are chosen according
to the host architecture. This will lead to a problem that if a thread
is run as x86_32 on a x86_64 machine, perf will use libunwind methods
for x86_64 to parse the callchain and get wrong results.

This patch changes the fixed methods of libunwind operations to be
thread/map related, and each thread can have individual libunwind
operations. Local libunwind methods are registered as default value.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-4-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/thread.h           |  4 ++-
 tools/perf/util/unwind-libunwind.c | 53 +++++++++++++++++++++++++++++++++++---
 tools/perf/util/unwind.h           |  9 +++++++
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 4c9f0aa11f1f..07ffb18221ab 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -11,6 +11,7 @@
 #include <intlist.h>
 
 struct thread_stack;
+struct unwind_libunwind_ops;
 
 struct thread {
 	union {
@@ -33,7 +34,8 @@ struct thread {
 	void			*priv;
 	struct thread_stack	*ts;
 #ifdef HAVE_LIBUNWIND_SUPPORT
-	void			*addr_space;
+	void				*addr_space;
+	struct unwind_libunwind_ops	*unwind_libunwind_ops;
 #endif
 };
 
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 63687d3a344e..b0c5db1333f9 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -579,7 +579,7 @@ static unw_accessors_t accessors = {
 	.get_proc_name		= get_proc_name,
 };
 
-int unwind__prepare_access(struct thread *thread)
+static int _unwind__prepare_access(struct thread *thread)
 {
 	if (callchain_param.record_mode != CALLCHAIN_DWARF)
 		return 0;
@@ -594,7 +594,7 @@ int unwind__prepare_access(struct thread *thread)
 	return 0;
 }
 
-void unwind__flush_access(struct thread *thread)
+static void _unwind__flush_access(struct thread *thread)
 {
 	if (callchain_param.record_mode != CALLCHAIN_DWARF)
 		return;
@@ -602,7 +602,7 @@ void unwind__flush_access(struct thread *thread)
 	unw_flush_cache(thread->addr_space, 0, 0);
 }
 
-void unwind__finish_access(struct thread *thread)
+static void _unwind__finish_access(struct thread *thread)
 {
 	if (callchain_param.record_mode != CALLCHAIN_DWARF)
 		return;
@@ -662,7 +662,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
 	return ret;
 }
 
-int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
+static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 			struct thread *thread,
 			struct perf_sample *data, int max_stack)
 {
@@ -680,3 +680,48 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 
 	return get_entries(&ui, cb, arg, max_stack);
 }
+
+static struct unwind_libunwind_ops
+_unwind_libunwind_ops = {
+	.prepare_access = _unwind__prepare_access,
+	.flush_access   = _unwind__flush_access,
+	.finish_access  = _unwind__finish_access,
+	.get_entries    = _unwind__get_entries,
+};
+
+struct unwind_libunwind_ops *
+local_unwind_libunwind_ops = &_unwind_libunwind_ops;
+
+static void unwind__register_ops(struct thread *thread,
+				 struct unwind_libunwind_ops *ops)
+{
+	thread->unwind_libunwind_ops = ops;
+}
+
+int unwind__prepare_access(struct thread *thread)
+{
+	unwind__register_ops(thread, local_unwind_libunwind_ops);
+
+	return thread->unwind_libunwind_ops->prepare_access(thread);
+}
+
+void unwind__flush_access(struct thread *thread)
+{
+	if (thread->unwind_libunwind_ops)
+		thread->unwind_libunwind_ops->flush_access(thread);
+}
+
+void unwind__finish_access(struct thread *thread)
+{
+	if (thread->unwind_libunwind_ops)
+		thread->unwind_libunwind_ops->finish_access(thread);
+}
+
+int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
+			 struct thread *thread,
+			 struct perf_sample *data, int max_stack)
+{
+	if (thread->unwind_libunwind_ops)
+		return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
+	return 0;
+}
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index 12790cf94618..bbd73d9bea45 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -14,6 +14,15 @@ 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 (*get_entries)(unwind_entry_cb_t cb, void *arg,
+			   struct thread *thread,
+			   struct perf_sample *data, int max_stack);
+};
+
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
 int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 			struct thread *thread,
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 14/24] perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (12 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 13/24] perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 15/24] perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS Arnaldo Carvalho de Melo
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

To determine the libunwind methods to use, we should get the
32bit/64bit information from maps of a thread. When a thread is newly
created, the information is not prepared. This patch moves
unwind__prepare_access() into thread__insert_map() so we can get the
information we need from maps. Meanwhile, let thread__insert_map()
return value and show messages on error.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-5-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/machine.c | 14 ++++++++++++--
 tools/perf/util/thread.c  | 13 +++++++++----
 tools/perf/util/thread.h  |  2 +-
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 205d27017361..9d931f5d47d0 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1353,11 +1353,16 @@ int machine__process_mmap2_event(struct machine *machine,
 	if (map == NULL)
 		goto out_problem_map;
 
-	thread__insert_map(thread, map);
+	ret = thread__insert_map(thread, map);
+	if (ret)
+		goto out_problem_insert;
+
 	thread__put(thread);
 	map__put(map);
 	return 0;
 
+out_problem_insert:
+	map__put(map);
 out_problem_map:
 	thread__put(thread);
 out_problem:
@@ -1403,11 +1408,16 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
 	if (map == NULL)
 		goto out_problem_map;
 
-	thread__insert_map(thread, map);
+	ret = thread__insert_map(thread, map);
+	if (ret)
+		goto out_problem_insert;
+
 	thread__put(thread);
 	map__put(map);
 	return 0;
 
+out_problem_insert:
+	map__put(map);
 out_problem_map:
 	thread__put(thread);
 out_problem:
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index ada58e6070bf..0bf552560a41 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -43,9 +43,6 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 		thread->cpu = -1;
 		INIT_LIST_HEAD(&thread->comm_list);
 
-		if (unwind__prepare_access(thread) < 0)
-			goto err_thread;
-
 		comm_str = malloc(32);
 		if (!comm_str)
 			goto err_thread;
@@ -201,10 +198,18 @@ size_t thread__fprintf(struct thread *thread, FILE *fp)
 	       map_groups__fprintf(thread->mg, fp);
 }
 
-void thread__insert_map(struct thread *thread, struct map *map)
+int thread__insert_map(struct thread *thread, struct map *map)
 {
+	int ret;
+
+	ret = unwind__prepare_access(thread);
+	if (ret)
+		return ret;
+
 	map_groups__fixup_overlappings(thread->mg, map, stderr);
 	map_groups__insert(thread->mg, map);
+
+	return 0;
 }
 
 static int thread__clone_map_groups(struct thread *thread,
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 07ffb18221ab..99263cb6e6b6 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -76,7 +76,7 @@ int thread__comm_len(struct thread *thread);
 struct comm *thread__comm(const struct thread *thread);
 struct comm *thread__exec_comm(const struct thread *thread);
 const char *thread__comm_str(const struct thread *thread);
-void thread__insert_map(struct thread *thread, struct map *map);
+int thread__insert_map(struct thread *thread, struct map *map);
 int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
 size_t thread__fprintf(struct thread *thread, FILE *fp);
 
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 15/24] perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (13 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 14/24] perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 16/24] perf unwind: Separate local/remote libunwind config Arnaldo Carvalho de Melo
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

LIBUNWIND_LIBS contains libunwind libraries used for local only, don't
mix this into LIBUNWIND_LDFLAGS so we can later use LIBUNWIND_LDFLAGS
both for local and remote libunwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-6-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/config/Makefile | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 6f9f566a757c..118df2d04b08 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -80,13 +80,12 @@ ifdef LIBUNWIND_DIR
   LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64
   $(foreach libunwind_arch,$(LIBUNWIND_ARCHS),$(call libunwind_arch_set_flags,$(libunwind_arch)))
 endif
-LIBUNWIND_LDFLAGS += $(LIBUNWIND_LIBS)
 
 # Set per-feature check compilation flags
 FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS)
-FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS)
+FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS)
 FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS)
-FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS)
+FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS)
 
 ifeq ($(NO_PERF_REGS),0)
   CFLAGS += -DHAVE_PERF_REGS_SUPPORT
@@ -409,7 +408,7 @@ ifndef NO_LIBUNWIND
   CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
   EXTLIBS += $(LIBUNWIND_LIBS)
   CFLAGS  += $(LIBUNWIND_CFLAGS)
-  LDFLAGS += $(LIBUNWIND_LDFLAGS)
+  LDFLAGS += $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS)
 endif
 
 ifndef NO_LIBAUDIT
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 16/24] perf unwind: Separate local/remote libunwind config
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (14 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 15/24] perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 17/24] perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c Arnaldo Carvalho de Melo
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

CONFIG_LIBUNWIND/NO_LIBUNWIND are changed to CONFIG_LOCAL_LIBUNWIND/
NO_LOCAL_LIBUNWIND for retaining local unwind features. The new
CONFIG_LIBUNWIND stands for either local or remote or both unwind are
supported, and NO_LIBUNWIND means that neither local nor remote unwind
is supported.

LIBUNWIND_LIBS is eliminated in LDFLAGS if local libunwind is not
supported.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-7-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/arm/util/Build   |  2 +-
 tools/perf/arch/arm64/util/Build |  2 +-
 tools/perf/arch/x86/util/Build   |  2 +-
 tools/perf/config/Makefile       | 20 +++++++++++++++++---
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build
index d22e3d07de3d..f98da17357c0 100644
--- a/tools/perf/arch/arm/util/Build
+++ b/tools/perf/arch/arm/util/Build
@@ -1,4 +1,4 @@
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 
-libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
+libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
index e58123a8912b..02f41dba4f4f 100644
--- a/tools/perf/arch/arm64/util/Build
+++ b/tools/perf/arch/arm64/util/Build
@@ -1,2 +1,2 @@
 libperf-$(CONFIG_DWARF)     += dwarf-regs.o
-libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o
+libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index 4cd8a16b1b7b..f95e6f46ef0d 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -8,7 +8,7 @@ libperf-y += group.o
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
 
-libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
+libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 
 libperf-$(CONFIG_AUXTRACE) += auxtrace.o
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 118df2d04b08..3918687e7816 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -353,10 +353,20 @@ ifeq ($(ARCH),powerpc)
 endif
 
 ifndef NO_LIBUNWIND
+  have_libunwind :=
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
+    NO_LOCAL_LIBUNWIND := 1
+  else
+    have_libunwind := 1
+    $(call detected,CONFIG_LOCAL_LIBUNWIND)
+  endif
+
+  ifneq ($(have_libunwind), 1)
     NO_LIBUNWIND := 1
   endif
+else
+  NO_LOCAL_LIBUNWIND := 1
 endif
 
 ifndef NO_LIBBPF
@@ -394,7 +404,7 @@ else
   NO_DWARF_UNWIND := 1
 endif
 
-ifndef NO_LIBUNWIND
+ifndef NO_LOCAL_LIBUNWIND
   ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
     $(call feature_check,libunwind-debug-frame)
     ifneq ($(feature-libunwind-debug-frame), 1)
@@ -405,10 +415,14 @@ ifndef NO_LIBUNWIND
     # non-ARM has no dwarf_find_debug_frame() function:
     CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
   endif
-  CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
   EXTLIBS += $(LIBUNWIND_LIBS)
+  LDFLAGS += $(LIBUNWIND_LIBS)
+endif
+
+ifndef NO_LIBUNWIND
+  CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
   CFLAGS  += $(LIBUNWIND_CFLAGS)
-  LDFLAGS += $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS)
+  LDFLAGS += $(LIBUNWIND_LDFLAGS)
 endif
 
 ifndef NO_LIBAUDIT
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 17/24] perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (15 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 16/24] perf unwind: Separate local/remote libunwind config Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 18/24] perf tools: Extract common API out of unwind-libunwind-local.c Arnaldo Carvalho de Melo
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Since unwind-libunwind.c contains code for specific arithecture, we
change it's name to unwind-libunwind-local.c, and let it only be built
if local libunwind is supported.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-8-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/Build                    |   2 +-
 tools/perf/util/unwind-libunwind-local.c | 727 +++++++++++++++++++++++++++++++
 tools/perf/util/unwind-libunwind.c       | 727 -------------------------------
 3 files changed, 728 insertions(+), 728 deletions(-)
 create mode 100644 tools/perf/util/unwind-libunwind-local.c
 delete mode 100644 tools/perf/util/unwind-libunwind.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 8c6c8a0ca642..5e23d85d2d69 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -99,7 +99,7 @@ libperf-$(CONFIG_DWARF) += probe-finder.o
 libperf-$(CONFIG_DWARF) += dwarf-aux.o
 
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
-libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
+libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
 
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
new file mode 100644
index 000000000000..b0c5db1333f9
--- /dev/null
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -0,0 +1,727 @@
+/*
+ * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps.
+ *
+ * Lots of this code have been borrowed or heavily inspired from parts of
+ * the libunwind 0.99 code which are (amongst other contributors I may have
+ * forgotten):
+ *
+ * Copyright (C) 2002-2007 Hewlett-Packard Co
+ *	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * And the bugs have been added by:
+ *
+ * Copyright (C) 2010, Frederic Weisbecker <fweisbec@gmail.com>
+ * Copyright (C) 2012, Jiri Olsa <jolsa@redhat.com>
+ *
+ */
+
+#include <elf.h>
+#include <gelf.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <linux/list.h>
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+#include "callchain.h"
+#include "thread.h"
+#include "session.h"
+#include "perf_regs.h"
+#include "unwind.h"
+#include "symbol.h"
+#include "util.h"
+#include "debug.h"
+#include "asm/bug.h"
+
+extern int
+UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+				    unw_word_t ip,
+				    unw_dyn_info_t *di,
+				    unw_proc_info_t *pi,
+				    int need_unwind_info, void *arg);
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+				 unw_word_t ip,
+				 unw_word_t segbase,
+				 const char *obj_name, unw_word_t start,
+				 unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
+#define DW_EH_PE_FORMAT_MASK	0x0f	/* format of the encoded value */
+#define DW_EH_PE_APPL_MASK	0x70	/* how the value is to be applied */
+
+/* Pointer-encoding formats: */
+#define DW_EH_PE_omit		0xff
+#define DW_EH_PE_ptr		0x00	/* pointer-sized unsigned value */
+#define DW_EH_PE_udata4		0x03	/* unsigned 32-bit value */
+#define DW_EH_PE_udata8		0x04	/* unsigned 64-bit value */
+#define DW_EH_PE_sdata4		0x0b	/* signed 32-bit value */
+#define DW_EH_PE_sdata8		0x0c	/* signed 64-bit value */
+
+/* Pointer-encoding application: */
+#define DW_EH_PE_absptr		0x00	/* absolute value */
+#define DW_EH_PE_pcrel		0x10	/* rel. to addr. of encoded value */
+
+/*
+ * The following are not documented by LSB v1.3, yet they are used by
+ * GCC, presumably they aren't documented by LSB since they aren't
+ * used on Linux:
+ */
+#define DW_EH_PE_funcrel	0x40	/* start-of-procedure-relative */
+#define DW_EH_PE_aligned	0x50	/* aligned pointer */
+
+/* Flags intentionaly not handled, since they're not needed:
+ * #define DW_EH_PE_indirect      0x80
+ * #define DW_EH_PE_uleb128       0x01
+ * #define DW_EH_PE_udata2        0x02
+ * #define DW_EH_PE_sleb128       0x09
+ * #define DW_EH_PE_sdata2        0x0a
+ * #define DW_EH_PE_textrel       0x20
+ * #define DW_EH_PE_datarel       0x30
+ */
+
+struct unwind_info {
+	struct perf_sample	*sample;
+	struct machine		*machine;
+	struct thread		*thread;
+};
+
+#define dw_read(ptr, type, end) ({	\
+	type *__p = (type *) ptr;	\
+	type  __v;			\
+	if ((__p + 1) > (type *) end)	\
+		return -EINVAL;		\
+	__v = *__p++;			\
+	ptr = (typeof(ptr)) __p;	\
+	__v;				\
+	})
+
+static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
+				   u8 encoding)
+{
+	u8 *cur = *p;
+	*val = 0;
+
+	switch (encoding) {
+	case DW_EH_PE_omit:
+		*val = 0;
+		goto out;
+	case DW_EH_PE_ptr:
+		*val = dw_read(cur, unsigned long, end);
+		goto out;
+	default:
+		break;
+	}
+
+	switch (encoding & DW_EH_PE_APPL_MASK) {
+	case DW_EH_PE_absptr:
+		break;
+	case DW_EH_PE_pcrel:
+		*val = (unsigned long) cur;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if ((encoding & 0x07) == 0x00)
+		encoding |= DW_EH_PE_udata4;
+
+	switch (encoding & DW_EH_PE_FORMAT_MASK) {
+	case DW_EH_PE_sdata4:
+		*val += dw_read(cur, s32, end);
+		break;
+	case DW_EH_PE_udata4:
+		*val += dw_read(cur, u32, end);
+		break;
+	case DW_EH_PE_sdata8:
+		*val += dw_read(cur, s64, end);
+		break;
+	case DW_EH_PE_udata8:
+		*val += dw_read(cur, u64, end);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+ out:
+	*p = cur;
+	return 0;
+}
+
+#define dw_read_encoded_value(ptr, end, enc) ({			\
+	u64 __v;						\
+	if (__dw_read_encoded_value(&ptr, end, &__v, enc)) {	\
+		return -EINVAL;                                 \
+	}                                                       \
+	__v;                                                    \
+	})
+
+static u64 elf_section_offset(int fd, const char *name)
+{
+	Elf *elf;
+	GElf_Ehdr ehdr;
+	GElf_Shdr shdr;
+	u64 offset = 0;
+
+	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+	if (elf == NULL)
+		return 0;
+
+	do {
+		if (gelf_getehdr(elf, &ehdr) == NULL)
+			break;
+
+		if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
+			break;
+
+		offset = shdr.sh_offset;
+	} while (0);
+
+	elf_end(elf);
+	return offset;
+}
+
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+static int elf_is_exec(int fd, const char *name)
+{
+	Elf *elf;
+	GElf_Ehdr ehdr;
+	int retval = 0;
+
+	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+	if (elf == NULL)
+		return 0;
+	if (gelf_getehdr(elf, &ehdr) == NULL)
+		goto out;
+
+	retval = (ehdr.e_type == ET_EXEC);
+
+out:
+	elf_end(elf);
+	pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
+	return retval;
+}
+#endif
+
+struct table_entry {
+	u32 start_ip_offset;
+	u32 fde_offset;
+};
+
+struct eh_frame_hdr {
+	unsigned char version;
+	unsigned char eh_frame_ptr_enc;
+	unsigned char fde_count_enc;
+	unsigned char table_enc;
+
+	/*
+	 * The rest of the header is variable-length and consists of the
+	 * following members:
+	 *
+	 *	encoded_t eh_frame_ptr;
+	 *	encoded_t fde_count;
+	 */
+
+	/* A single encoded pointer should not be more than 8 bytes. */
+	u64 enc[2];
+
+	/*
+	 * struct {
+	 *    encoded_t start_ip;
+	 *    encoded_t fde_addr;
+	 * } binary_search_table[fde_count];
+	 */
+	char data[0];
+} __packed;
+
+static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
+			       u64 offset, u64 *table_data, u64 *segbase,
+			       u64 *fde_count)
+{
+	struct eh_frame_hdr hdr;
+	u8 *enc = (u8 *) &hdr.enc;
+	u8 *end = (u8 *) &hdr.data;
+	ssize_t r;
+
+	r = dso__data_read_offset(dso, machine, offset,
+				  (u8 *) &hdr, sizeof(hdr));
+	if (r != sizeof(hdr))
+		return -EINVAL;
+
+	/* We dont need eh_frame_ptr, just skip it. */
+	dw_read_encoded_value(enc, end, hdr.eh_frame_ptr_enc);
+
+	*fde_count  = dw_read_encoded_value(enc, end, hdr.fde_count_enc);
+	*segbase    = offset;
+	*table_data = (enc - (u8 *) &hdr) + offset;
+	return 0;
+}
+
+static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
+				     u64 *table_data, u64 *segbase,
+				     u64 *fde_count)
+{
+	int ret = -EINVAL, fd;
+	u64 offset = dso->data.eh_frame_hdr_offset;
+
+	if (offset == 0) {
+		fd = dso__data_get_fd(dso, machine);
+		if (fd < 0)
+			return -EINVAL;
+
+		/* Check the .eh_frame section for unwinding info */
+		offset = elf_section_offset(fd, ".eh_frame_hdr");
+		dso->data.eh_frame_hdr_offset = offset;
+		dso__data_put_fd(dso);
+	}
+
+	if (offset)
+		ret = unwind_spec_ehframe(dso, machine, offset,
+					  table_data, segbase,
+					  fde_count);
+
+	return ret;
+}
+
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+static int read_unwind_spec_debug_frame(struct dso *dso,
+					struct machine *machine, u64 *offset)
+{
+	int fd;
+	u64 ofs = dso->data.debug_frame_offset;
+
+	if (ofs == 0) {
+		fd = dso__data_get_fd(dso, machine);
+		if (fd < 0)
+			return -EINVAL;
+
+		/* Check the .debug_frame section for unwinding info */
+		ofs = elf_section_offset(fd, ".debug_frame");
+		dso->data.debug_frame_offset = ofs;
+		dso__data_put_fd(dso);
+	}
+
+	*offset = ofs;
+	if (*offset)
+		return 0;
+
+	return -EINVAL;
+}
+#endif
+
+static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
+{
+	struct addr_location al;
+
+	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
+			      MAP__FUNCTION, ip, &al);
+	if (!al.map) {
+		/*
+		 * We've seen cases (softice) where DWARF unwinder went
+		 * through non executable mmaps, which we need to lookup
+		 * in MAP__VARIABLE tree.
+		 */
+		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
+				      MAP__VARIABLE, ip, &al);
+	}
+	return al.map;
+}
+
+static int
+find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
+	       int need_unwind_info, void *arg)
+{
+	struct unwind_info *ui = arg;
+	struct map *map;
+	unw_dyn_info_t di;
+	u64 table_data, segbase, fde_count;
+	int ret = -EINVAL;
+
+	map = find_map(ip, ui);
+	if (!map || !map->dso)
+		return -EINVAL;
+
+	pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
+
+	/* Check the .eh_frame section for unwinding info */
+	if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
+				       &table_data, &segbase, &fde_count)) {
+		memset(&di, 0, sizeof(di));
+		di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
+		di.start_ip = map->start;
+		di.end_ip   = map->end;
+		di.u.rti.segbase    = map->start + segbase;
+		di.u.rti.table_data = map->start + table_data;
+		di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
+				      / sizeof(unw_word_t);
+		ret = dwarf_search_unwind_table(as, ip, &di, pi,
+						need_unwind_info, arg);
+	}
+
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+	/* Check the .debug_frame section for unwinding info */
+	if (ret < 0 &&
+	    !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
+		int fd = dso__data_get_fd(map->dso, ui->machine);
+		int is_exec = elf_is_exec(fd, map->dso->name);
+		unw_word_t base = is_exec ? 0 : map->start;
+		const char *symfile;
+
+		if (fd >= 0)
+			dso__data_put_fd(map->dso);
+
+		symfile = map->dso->symsrc_filename ?: map->dso->name;
+
+		memset(&di, 0, sizeof(di));
+		if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
+					   map->start, map->end))
+			return dwarf_search_unwind_table(as, ip, &di, pi,
+							 need_unwind_info, arg);
+	}
+#endif
+
+	return ret;
+}
+
+static int access_fpreg(unw_addr_space_t __maybe_unused as,
+			unw_regnum_t __maybe_unused num,
+			unw_fpreg_t __maybe_unused *val,
+			int __maybe_unused __write,
+			void __maybe_unused *arg)
+{
+	pr_err("unwind: access_fpreg unsupported\n");
+	return -UNW_EINVAL;
+}
+
+static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
+				  unw_word_t __maybe_unused *dil_addr,
+				  void __maybe_unused *arg)
+{
+	return -UNW_ENOINFO;
+}
+
+static int resume(unw_addr_space_t __maybe_unused as,
+		  unw_cursor_t __maybe_unused *cu,
+		  void __maybe_unused *arg)
+{
+	pr_err("unwind: resume unsupported\n");
+	return -UNW_EINVAL;
+}
+
+static int
+get_proc_name(unw_addr_space_t __maybe_unused as,
+	      unw_word_t __maybe_unused addr,
+		char __maybe_unused *bufp, size_t __maybe_unused buf_len,
+		unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
+{
+	pr_err("unwind: get_proc_name unsupported\n");
+	return -UNW_EINVAL;
+}
+
+static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
+			  unw_word_t *data)
+{
+	struct map *map;
+	ssize_t size;
+
+	map = find_map(addr, ui);
+	if (!map) {
+		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
+		return -1;
+	}
+
+	if (!map->dso)
+		return -1;
+
+	size = dso__data_read_addr(map->dso, map, ui->machine,
+				   addr, (u8 *) data, sizeof(*data));
+
+	return !(size == sizeof(*data));
+}
+
+static int access_mem(unw_addr_space_t __maybe_unused as,
+		      unw_word_t addr, unw_word_t *valp,
+		      int __write, void *arg)
+{
+	struct unwind_info *ui = arg;
+	struct stack_dump *stack = &ui->sample->user_stack;
+	u64 start, end;
+	int offset;
+	int ret;
+
+	/* Don't support write, probably not needed. */
+	if (__write || !stack || !ui->sample->user_regs.regs) {
+		*valp = 0;
+		return 0;
+	}
+
+	ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
+	if (ret)
+		return ret;
+
+	end = start + stack->size;
+
+	/* Check overflow. */
+	if (addr + sizeof(unw_word_t) < addr)
+		return -EINVAL;
+
+	if (addr < start || addr + sizeof(unw_word_t) >= end) {
+		ret = access_dso_mem(ui, addr, valp);
+		if (ret) {
+			pr_debug("unwind: access_mem %p not inside range"
+				 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
+				 (void *) (uintptr_t) addr, start, end);
+			*valp = 0;
+			return ret;
+		}
+		return 0;
+	}
+
+	offset = addr - start;
+	*valp  = *(unw_word_t *)&stack->data[offset];
+	pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
+		 (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
+	return 0;
+}
+
+static int access_reg(unw_addr_space_t __maybe_unused as,
+		      unw_regnum_t regnum, unw_word_t *valp,
+		      int __write, void *arg)
+{
+	struct unwind_info *ui = arg;
+	int id, ret;
+	u64 val;
+
+	/* Don't support write, I suspect we don't need it. */
+	if (__write) {
+		pr_err("unwind: access_reg w %d\n", regnum);
+		return 0;
+	}
+
+	if (!ui->sample->user_regs.regs) {
+		*valp = 0;
+		return 0;
+	}
+
+	id = libunwind__arch_reg_id(regnum);
+	if (id < 0)
+		return -EINVAL;
+
+	ret = perf_reg_value(&val, &ui->sample->user_regs, id);
+	if (ret) {
+		pr_err("unwind: can't read reg %d\n", regnum);
+		return ret;
+	}
+
+	*valp = (unw_word_t) val;
+	pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
+	return 0;
+}
+
+static void put_unwind_info(unw_addr_space_t __maybe_unused as,
+			    unw_proc_info_t *pi __maybe_unused,
+			    void *arg __maybe_unused)
+{
+	pr_debug("unwind: put_unwind_info called\n");
+}
+
+static int entry(u64 ip, struct thread *thread,
+		 unwind_entry_cb_t cb, void *arg)
+{
+	struct unwind_entry e;
+	struct addr_location al;
+
+	thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
+				   MAP__FUNCTION, ip, &al);
+
+	e.ip = ip;
+	e.map = al.map;
+	e.sym = al.sym;
+
+	pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
+		 al.sym ? al.sym->name : "''",
+		 ip,
+		 al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
+
+	return cb(&e, arg);
+}
+
+static void display_error(int err)
+{
+	switch (err) {
+	case UNW_EINVAL:
+		pr_err("unwind: Only supports local.\n");
+		break;
+	case UNW_EUNSPEC:
+		pr_err("unwind: Unspecified error.\n");
+		break;
+	case UNW_EBADREG:
+		pr_err("unwind: Register unavailable.\n");
+		break;
+	default:
+		break;
+	}
+}
+
+static unw_accessors_t accessors = {
+	.find_proc_info		= find_proc_info,
+	.put_unwind_info	= put_unwind_info,
+	.get_dyn_info_list_addr	= get_dyn_info_list_addr,
+	.access_mem		= access_mem,
+	.access_reg		= access_reg,
+	.access_fpreg		= access_fpreg,
+	.resume			= resume,
+	.get_proc_name		= get_proc_name,
+};
+
+static int _unwind__prepare_access(struct thread *thread)
+{
+	if (callchain_param.record_mode != CALLCHAIN_DWARF)
+		return 0;
+
+	thread->addr_space = unw_create_addr_space(&accessors, 0);
+	if (!thread->addr_space) {
+		pr_err("unwind: Can't create unwind address space.\n");
+		return -ENOMEM;
+	}
+
+	unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
+	return 0;
+}
+
+static void _unwind__flush_access(struct thread *thread)
+{
+	if (callchain_param.record_mode != CALLCHAIN_DWARF)
+		return;
+
+	unw_flush_cache(thread->addr_space, 0, 0);
+}
+
+static void _unwind__finish_access(struct thread *thread)
+{
+	if (callchain_param.record_mode != CALLCHAIN_DWARF)
+		return;
+
+	unw_destroy_addr_space(thread->addr_space);
+}
+
+static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
+		       void *arg, int max_stack)
+{
+	u64 val;
+	unw_word_t ips[max_stack];
+	unw_addr_space_t addr_space;
+	unw_cursor_t c;
+	int ret, i = 0;
+
+	ret = perf_reg_value(&val, &ui->sample->user_regs, PERF_REG_IP);
+	if (ret)
+		return ret;
+
+	ips[i++] = (unw_word_t) val;
+
+	/*
+	 * If we need more than one entry, do the DWARF
+	 * unwind itself.
+	 */
+	if (max_stack - 1 > 0) {
+		WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
+		addr_space = ui->thread->addr_space;
+
+		if (addr_space == NULL)
+			return -1;
+
+		ret = unw_init_remote(&c, addr_space, ui);
+		if (ret)
+			display_error(ret);
+
+		while (!ret && (unw_step(&c) > 0) && i < max_stack) {
+			unw_get_reg(&c, UNW_REG_IP, &ips[i]);
+			++i;
+		}
+
+		max_stack = i;
+	}
+
+	/*
+	 * Display what we got based on the order setup.
+	 */
+	for (i = 0; i < max_stack && !ret; i++) {
+		int j = i;
+
+		if (callchain_param.order == ORDER_CALLER)
+			j = max_stack - i - 1;
+		ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0;
+	}
+
+	return ret;
+}
+
+static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg,
+			struct thread *thread,
+			struct perf_sample *data, int max_stack)
+{
+	struct unwind_info ui = {
+		.sample       = data,
+		.thread       = thread,
+		.machine      = thread->mg->machine,
+	};
+
+	if (!data->user_regs.regs)
+		return -EINVAL;
+
+	if (max_stack <= 0)
+		return -EINVAL;
+
+	return get_entries(&ui, cb, arg, max_stack);
+}
+
+static struct unwind_libunwind_ops
+_unwind_libunwind_ops = {
+	.prepare_access = _unwind__prepare_access,
+	.flush_access   = _unwind__flush_access,
+	.finish_access  = _unwind__finish_access,
+	.get_entries    = _unwind__get_entries,
+};
+
+struct unwind_libunwind_ops *
+local_unwind_libunwind_ops = &_unwind_libunwind_ops;
+
+static void unwind__register_ops(struct thread *thread,
+				 struct unwind_libunwind_ops *ops)
+{
+	thread->unwind_libunwind_ops = ops;
+}
+
+int unwind__prepare_access(struct thread *thread)
+{
+	unwind__register_ops(thread, local_unwind_libunwind_ops);
+
+	return thread->unwind_libunwind_ops->prepare_access(thread);
+}
+
+void unwind__flush_access(struct thread *thread)
+{
+	if (thread->unwind_libunwind_ops)
+		thread->unwind_libunwind_ops->flush_access(thread);
+}
+
+void unwind__finish_access(struct thread *thread)
+{
+	if (thread->unwind_libunwind_ops)
+		thread->unwind_libunwind_ops->finish_access(thread);
+}
+
+int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
+			 struct thread *thread,
+			 struct perf_sample *data, int max_stack)
+{
+	if (thread->unwind_libunwind_ops)
+		return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
+	return 0;
+}
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
deleted file mode 100644
index b0c5db1333f9..000000000000
--- a/tools/perf/util/unwind-libunwind.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps.
- *
- * Lots of this code have been borrowed or heavily inspired from parts of
- * the libunwind 0.99 code which are (amongst other contributors I may have
- * forgotten):
- *
- * Copyright (C) 2002-2007 Hewlett-Packard Co
- *	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * And the bugs have been added by:
- *
- * Copyright (C) 2010, Frederic Weisbecker <fweisbec@gmail.com>
- * Copyright (C) 2012, Jiri Olsa <jolsa@redhat.com>
- *
- */
-
-#include <elf.h>
-#include <gelf.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <linux/list.h>
-#include <libunwind.h>
-#include <libunwind-ptrace.h>
-#include "callchain.h"
-#include "thread.h"
-#include "session.h"
-#include "perf_regs.h"
-#include "unwind.h"
-#include "symbol.h"
-#include "util.h"
-#include "debug.h"
-#include "asm/bug.h"
-
-extern int
-UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
-				    unw_word_t ip,
-				    unw_dyn_info_t *di,
-				    unw_proc_info_t *pi,
-				    int need_unwind_info, void *arg);
-
-#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
-
-extern int
-UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
-				 unw_word_t ip,
-				 unw_word_t segbase,
-				 const char *obj_name, unw_word_t start,
-				 unw_word_t end);
-
-#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
-
-#define DW_EH_PE_FORMAT_MASK	0x0f	/* format of the encoded value */
-#define DW_EH_PE_APPL_MASK	0x70	/* how the value is to be applied */
-
-/* Pointer-encoding formats: */
-#define DW_EH_PE_omit		0xff
-#define DW_EH_PE_ptr		0x00	/* pointer-sized unsigned value */
-#define DW_EH_PE_udata4		0x03	/* unsigned 32-bit value */
-#define DW_EH_PE_udata8		0x04	/* unsigned 64-bit value */
-#define DW_EH_PE_sdata4		0x0b	/* signed 32-bit value */
-#define DW_EH_PE_sdata8		0x0c	/* signed 64-bit value */
-
-/* Pointer-encoding application: */
-#define DW_EH_PE_absptr		0x00	/* absolute value */
-#define DW_EH_PE_pcrel		0x10	/* rel. to addr. of encoded value */
-
-/*
- * The following are not documented by LSB v1.3, yet they are used by
- * GCC, presumably they aren't documented by LSB since they aren't
- * used on Linux:
- */
-#define DW_EH_PE_funcrel	0x40	/* start-of-procedure-relative */
-#define DW_EH_PE_aligned	0x50	/* aligned pointer */
-
-/* Flags intentionaly not handled, since they're not needed:
- * #define DW_EH_PE_indirect      0x80
- * #define DW_EH_PE_uleb128       0x01
- * #define DW_EH_PE_udata2        0x02
- * #define DW_EH_PE_sleb128       0x09
- * #define DW_EH_PE_sdata2        0x0a
- * #define DW_EH_PE_textrel       0x20
- * #define DW_EH_PE_datarel       0x30
- */
-
-struct unwind_info {
-	struct perf_sample	*sample;
-	struct machine		*machine;
-	struct thread		*thread;
-};
-
-#define dw_read(ptr, type, end) ({	\
-	type *__p = (type *) ptr;	\
-	type  __v;			\
-	if ((__p + 1) > (type *) end)	\
-		return -EINVAL;		\
-	__v = *__p++;			\
-	ptr = (typeof(ptr)) __p;	\
-	__v;				\
-	})
-
-static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
-				   u8 encoding)
-{
-	u8 *cur = *p;
-	*val = 0;
-
-	switch (encoding) {
-	case DW_EH_PE_omit:
-		*val = 0;
-		goto out;
-	case DW_EH_PE_ptr:
-		*val = dw_read(cur, unsigned long, end);
-		goto out;
-	default:
-		break;
-	}
-
-	switch (encoding & DW_EH_PE_APPL_MASK) {
-	case DW_EH_PE_absptr:
-		break;
-	case DW_EH_PE_pcrel:
-		*val = (unsigned long) cur;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if ((encoding & 0x07) == 0x00)
-		encoding |= DW_EH_PE_udata4;
-
-	switch (encoding & DW_EH_PE_FORMAT_MASK) {
-	case DW_EH_PE_sdata4:
-		*val += dw_read(cur, s32, end);
-		break;
-	case DW_EH_PE_udata4:
-		*val += dw_read(cur, u32, end);
-		break;
-	case DW_EH_PE_sdata8:
-		*val += dw_read(cur, s64, end);
-		break;
-	case DW_EH_PE_udata8:
-		*val += dw_read(cur, u64, end);
-		break;
-	default:
-		return -EINVAL;
-	}
-
- out:
-	*p = cur;
-	return 0;
-}
-
-#define dw_read_encoded_value(ptr, end, enc) ({			\
-	u64 __v;						\
-	if (__dw_read_encoded_value(&ptr, end, &__v, enc)) {	\
-		return -EINVAL;                                 \
-	}                                                       \
-	__v;                                                    \
-	})
-
-static u64 elf_section_offset(int fd, const char *name)
-{
-	Elf *elf;
-	GElf_Ehdr ehdr;
-	GElf_Shdr shdr;
-	u64 offset = 0;
-
-	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
-	if (elf == NULL)
-		return 0;
-
-	do {
-		if (gelf_getehdr(elf, &ehdr) == NULL)
-			break;
-
-		if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
-			break;
-
-		offset = shdr.sh_offset;
-	} while (0);
-
-	elf_end(elf);
-	return offset;
-}
-
-#ifndef NO_LIBUNWIND_DEBUG_FRAME
-static int elf_is_exec(int fd, const char *name)
-{
-	Elf *elf;
-	GElf_Ehdr ehdr;
-	int retval = 0;
-
-	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
-	if (elf == NULL)
-		return 0;
-	if (gelf_getehdr(elf, &ehdr) == NULL)
-		goto out;
-
-	retval = (ehdr.e_type == ET_EXEC);
-
-out:
-	elf_end(elf);
-	pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
-	return retval;
-}
-#endif
-
-struct table_entry {
-	u32 start_ip_offset;
-	u32 fde_offset;
-};
-
-struct eh_frame_hdr {
-	unsigned char version;
-	unsigned char eh_frame_ptr_enc;
-	unsigned char fde_count_enc;
-	unsigned char table_enc;
-
-	/*
-	 * The rest of the header is variable-length and consists of the
-	 * following members:
-	 *
-	 *	encoded_t eh_frame_ptr;
-	 *	encoded_t fde_count;
-	 */
-
-	/* A single encoded pointer should not be more than 8 bytes. */
-	u64 enc[2];
-
-	/*
-	 * struct {
-	 *    encoded_t start_ip;
-	 *    encoded_t fde_addr;
-	 * } binary_search_table[fde_count];
-	 */
-	char data[0];
-} __packed;
-
-static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
-			       u64 offset, u64 *table_data, u64 *segbase,
-			       u64 *fde_count)
-{
-	struct eh_frame_hdr hdr;
-	u8 *enc = (u8 *) &hdr.enc;
-	u8 *end = (u8 *) &hdr.data;
-	ssize_t r;
-
-	r = dso__data_read_offset(dso, machine, offset,
-				  (u8 *) &hdr, sizeof(hdr));
-	if (r != sizeof(hdr))
-		return -EINVAL;
-
-	/* We dont need eh_frame_ptr, just skip it. */
-	dw_read_encoded_value(enc, end, hdr.eh_frame_ptr_enc);
-
-	*fde_count  = dw_read_encoded_value(enc, end, hdr.fde_count_enc);
-	*segbase    = offset;
-	*table_data = (enc - (u8 *) &hdr) + offset;
-	return 0;
-}
-
-static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
-				     u64 *table_data, u64 *segbase,
-				     u64 *fde_count)
-{
-	int ret = -EINVAL, fd;
-	u64 offset = dso->data.eh_frame_hdr_offset;
-
-	if (offset == 0) {
-		fd = dso__data_get_fd(dso, machine);
-		if (fd < 0)
-			return -EINVAL;
-
-		/* Check the .eh_frame section for unwinding info */
-		offset = elf_section_offset(fd, ".eh_frame_hdr");
-		dso->data.eh_frame_hdr_offset = offset;
-		dso__data_put_fd(dso);
-	}
-
-	if (offset)
-		ret = unwind_spec_ehframe(dso, machine, offset,
-					  table_data, segbase,
-					  fde_count);
-
-	return ret;
-}
-
-#ifndef NO_LIBUNWIND_DEBUG_FRAME
-static int read_unwind_spec_debug_frame(struct dso *dso,
-					struct machine *machine, u64 *offset)
-{
-	int fd;
-	u64 ofs = dso->data.debug_frame_offset;
-
-	if (ofs == 0) {
-		fd = dso__data_get_fd(dso, machine);
-		if (fd < 0)
-			return -EINVAL;
-
-		/* Check the .debug_frame section for unwinding info */
-		ofs = elf_section_offset(fd, ".debug_frame");
-		dso->data.debug_frame_offset = ofs;
-		dso__data_put_fd(dso);
-	}
-
-	*offset = ofs;
-	if (*offset)
-		return 0;
-
-	return -EINVAL;
-}
-#endif
-
-static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
-{
-	struct addr_location al;
-
-	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
-			      MAP__FUNCTION, ip, &al);
-	if (!al.map) {
-		/*
-		 * We've seen cases (softice) where DWARF unwinder went
-		 * through non executable mmaps, which we need to lookup
-		 * in MAP__VARIABLE tree.
-		 */
-		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
-				      MAP__VARIABLE, ip, &al);
-	}
-	return al.map;
-}
-
-static int
-find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
-	       int need_unwind_info, void *arg)
-{
-	struct unwind_info *ui = arg;
-	struct map *map;
-	unw_dyn_info_t di;
-	u64 table_data, segbase, fde_count;
-	int ret = -EINVAL;
-
-	map = find_map(ip, ui);
-	if (!map || !map->dso)
-		return -EINVAL;
-
-	pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
-
-	/* Check the .eh_frame section for unwinding info */
-	if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
-				       &table_data, &segbase, &fde_count)) {
-		memset(&di, 0, sizeof(di));
-		di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
-		di.start_ip = map->start;
-		di.end_ip   = map->end;
-		di.u.rti.segbase    = map->start + segbase;
-		di.u.rti.table_data = map->start + table_data;
-		di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
-				      / sizeof(unw_word_t);
-		ret = dwarf_search_unwind_table(as, ip, &di, pi,
-						need_unwind_info, arg);
-	}
-
-#ifndef NO_LIBUNWIND_DEBUG_FRAME
-	/* Check the .debug_frame section for unwinding info */
-	if (ret < 0 &&
-	    !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
-		int fd = dso__data_get_fd(map->dso, ui->machine);
-		int is_exec = elf_is_exec(fd, map->dso->name);
-		unw_word_t base = is_exec ? 0 : map->start;
-		const char *symfile;
-
-		if (fd >= 0)
-			dso__data_put_fd(map->dso);
-
-		symfile = map->dso->symsrc_filename ?: map->dso->name;
-
-		memset(&di, 0, sizeof(di));
-		if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
-					   map->start, map->end))
-			return dwarf_search_unwind_table(as, ip, &di, pi,
-							 need_unwind_info, arg);
-	}
-#endif
-
-	return ret;
-}
-
-static int access_fpreg(unw_addr_space_t __maybe_unused as,
-			unw_regnum_t __maybe_unused num,
-			unw_fpreg_t __maybe_unused *val,
-			int __maybe_unused __write,
-			void __maybe_unused *arg)
-{
-	pr_err("unwind: access_fpreg unsupported\n");
-	return -UNW_EINVAL;
-}
-
-static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
-				  unw_word_t __maybe_unused *dil_addr,
-				  void __maybe_unused *arg)
-{
-	return -UNW_ENOINFO;
-}
-
-static int resume(unw_addr_space_t __maybe_unused as,
-		  unw_cursor_t __maybe_unused *cu,
-		  void __maybe_unused *arg)
-{
-	pr_err("unwind: resume unsupported\n");
-	return -UNW_EINVAL;
-}
-
-static int
-get_proc_name(unw_addr_space_t __maybe_unused as,
-	      unw_word_t __maybe_unused addr,
-		char __maybe_unused *bufp, size_t __maybe_unused buf_len,
-		unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
-{
-	pr_err("unwind: get_proc_name unsupported\n");
-	return -UNW_EINVAL;
-}
-
-static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
-			  unw_word_t *data)
-{
-	struct map *map;
-	ssize_t size;
-
-	map = find_map(addr, ui);
-	if (!map) {
-		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
-		return -1;
-	}
-
-	if (!map->dso)
-		return -1;
-
-	size = dso__data_read_addr(map->dso, map, ui->machine,
-				   addr, (u8 *) data, sizeof(*data));
-
-	return !(size == sizeof(*data));
-}
-
-static int access_mem(unw_addr_space_t __maybe_unused as,
-		      unw_word_t addr, unw_word_t *valp,
-		      int __write, void *arg)
-{
-	struct unwind_info *ui = arg;
-	struct stack_dump *stack = &ui->sample->user_stack;
-	u64 start, end;
-	int offset;
-	int ret;
-
-	/* Don't support write, probably not needed. */
-	if (__write || !stack || !ui->sample->user_regs.regs) {
-		*valp = 0;
-		return 0;
-	}
-
-	ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
-	if (ret)
-		return ret;
-
-	end = start + stack->size;
-
-	/* Check overflow. */
-	if (addr + sizeof(unw_word_t) < addr)
-		return -EINVAL;
-
-	if (addr < start || addr + sizeof(unw_word_t) >= end) {
-		ret = access_dso_mem(ui, addr, valp);
-		if (ret) {
-			pr_debug("unwind: access_mem %p not inside range"
-				 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
-				 (void *) (uintptr_t) addr, start, end);
-			*valp = 0;
-			return ret;
-		}
-		return 0;
-	}
-
-	offset = addr - start;
-	*valp  = *(unw_word_t *)&stack->data[offset];
-	pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
-		 (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
-	return 0;
-}
-
-static int access_reg(unw_addr_space_t __maybe_unused as,
-		      unw_regnum_t regnum, unw_word_t *valp,
-		      int __write, void *arg)
-{
-	struct unwind_info *ui = arg;
-	int id, ret;
-	u64 val;
-
-	/* Don't support write, I suspect we don't need it. */
-	if (__write) {
-		pr_err("unwind: access_reg w %d\n", regnum);
-		return 0;
-	}
-
-	if (!ui->sample->user_regs.regs) {
-		*valp = 0;
-		return 0;
-	}
-
-	id = libunwind__arch_reg_id(regnum);
-	if (id < 0)
-		return -EINVAL;
-
-	ret = perf_reg_value(&val, &ui->sample->user_regs, id);
-	if (ret) {
-		pr_err("unwind: can't read reg %d\n", regnum);
-		return ret;
-	}
-
-	*valp = (unw_word_t) val;
-	pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
-	return 0;
-}
-
-static void put_unwind_info(unw_addr_space_t __maybe_unused as,
-			    unw_proc_info_t *pi __maybe_unused,
-			    void *arg __maybe_unused)
-{
-	pr_debug("unwind: put_unwind_info called\n");
-}
-
-static int entry(u64 ip, struct thread *thread,
-		 unwind_entry_cb_t cb, void *arg)
-{
-	struct unwind_entry e;
-	struct addr_location al;
-
-	thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
-				   MAP__FUNCTION, ip, &al);
-
-	e.ip = ip;
-	e.map = al.map;
-	e.sym = al.sym;
-
-	pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
-		 al.sym ? al.sym->name : "''",
-		 ip,
-		 al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
-
-	return cb(&e, arg);
-}
-
-static void display_error(int err)
-{
-	switch (err) {
-	case UNW_EINVAL:
-		pr_err("unwind: Only supports local.\n");
-		break;
-	case UNW_EUNSPEC:
-		pr_err("unwind: Unspecified error.\n");
-		break;
-	case UNW_EBADREG:
-		pr_err("unwind: Register unavailable.\n");
-		break;
-	default:
-		break;
-	}
-}
-
-static unw_accessors_t accessors = {
-	.find_proc_info		= find_proc_info,
-	.put_unwind_info	= put_unwind_info,
-	.get_dyn_info_list_addr	= get_dyn_info_list_addr,
-	.access_mem		= access_mem,
-	.access_reg		= access_reg,
-	.access_fpreg		= access_fpreg,
-	.resume			= resume,
-	.get_proc_name		= get_proc_name,
-};
-
-static int _unwind__prepare_access(struct thread *thread)
-{
-	if (callchain_param.record_mode != CALLCHAIN_DWARF)
-		return 0;
-
-	thread->addr_space = unw_create_addr_space(&accessors, 0);
-	if (!thread->addr_space) {
-		pr_err("unwind: Can't create unwind address space.\n");
-		return -ENOMEM;
-	}
-
-	unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
-	return 0;
-}
-
-static void _unwind__flush_access(struct thread *thread)
-{
-	if (callchain_param.record_mode != CALLCHAIN_DWARF)
-		return;
-
-	unw_flush_cache(thread->addr_space, 0, 0);
-}
-
-static void _unwind__finish_access(struct thread *thread)
-{
-	if (callchain_param.record_mode != CALLCHAIN_DWARF)
-		return;
-
-	unw_destroy_addr_space(thread->addr_space);
-}
-
-static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
-		       void *arg, int max_stack)
-{
-	u64 val;
-	unw_word_t ips[max_stack];
-	unw_addr_space_t addr_space;
-	unw_cursor_t c;
-	int ret, i = 0;
-
-	ret = perf_reg_value(&val, &ui->sample->user_regs, PERF_REG_IP);
-	if (ret)
-		return ret;
-
-	ips[i++] = (unw_word_t) val;
-
-	/*
-	 * If we need more than one entry, do the DWARF
-	 * unwind itself.
-	 */
-	if (max_stack - 1 > 0) {
-		WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
-		addr_space = ui->thread->addr_space;
-
-		if (addr_space == NULL)
-			return -1;
-
-		ret = unw_init_remote(&c, addr_space, ui);
-		if (ret)
-			display_error(ret);
-
-		while (!ret && (unw_step(&c) > 0) && i < max_stack) {
-			unw_get_reg(&c, UNW_REG_IP, &ips[i]);
-			++i;
-		}
-
-		max_stack = i;
-	}
-
-	/*
-	 * Display what we got based on the order setup.
-	 */
-	for (i = 0; i < max_stack && !ret; i++) {
-		int j = i;
-
-		if (callchain_param.order == ORDER_CALLER)
-			j = max_stack - i - 1;
-		ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0;
-	}
-
-	return ret;
-}
-
-static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg,
-			struct thread *thread,
-			struct perf_sample *data, int max_stack)
-{
-	struct unwind_info ui = {
-		.sample       = data,
-		.thread       = thread,
-		.machine      = thread->mg->machine,
-	};
-
-	if (!data->user_regs.regs)
-		return -EINVAL;
-
-	if (max_stack <= 0)
-		return -EINVAL;
-
-	return get_entries(&ui, cb, arg, max_stack);
-}
-
-static struct unwind_libunwind_ops
-_unwind_libunwind_ops = {
-	.prepare_access = _unwind__prepare_access,
-	.flush_access   = _unwind__flush_access,
-	.finish_access  = _unwind__finish_access,
-	.get_entries    = _unwind__get_entries,
-};
-
-struct unwind_libunwind_ops *
-local_unwind_libunwind_ops = &_unwind_libunwind_ops;
-
-static void unwind__register_ops(struct thread *thread,
-				 struct unwind_libunwind_ops *ops)
-{
-	thread->unwind_libunwind_ops = ops;
-}
-
-int unwind__prepare_access(struct thread *thread)
-{
-	unwind__register_ops(thread, local_unwind_libunwind_ops);
-
-	return thread->unwind_libunwind_ops->prepare_access(thread);
-}
-
-void unwind__flush_access(struct thread *thread)
-{
-	if (thread->unwind_libunwind_ops)
-		thread->unwind_libunwind_ops->flush_access(thread);
-}
-
-void unwind__finish_access(struct thread *thread)
-{
-	if (thread->unwind_libunwind_ops)
-		thread->unwind_libunwind_ops->finish_access(thread);
-}
-
-int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
-			 struct thread *thread,
-			 struct perf_sample *data, int max_stack)
-{
-	if (thread->unwind_libunwind_ops)
-		return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
-	return 0;
-}
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 18/24] perf tools: Extract common API out of unwind-libunwind-local.c
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (16 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 17/24] perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 19/24] perf tools: Export normalize_arch() function Arnaldo Carvalho de Melo
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

This patch extracts common unwind-libunwind APIs out of
unwind-libunwind-local.c, this part will be used by both local and
remote libunwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-9-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/Build                    |  1 +
 tools/perf/util/unwind-libunwind-local.c | 34 ----------------------------
 tools/perf/util/unwind-libunwind.c       | 38 ++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 34 deletions(-)
 create mode 100644 tools/perf/util/unwind-libunwind.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 5e23d85d2d69..004fb1d1d0ad 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -100,6 +100,7 @@ libperf-$(CONFIG_DWARF) += dwarf-aux.o
 
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
+libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
 
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index b0c5db1333f9..9c70486c5c6a 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -691,37 +691,3 @@ _unwind_libunwind_ops = {
 
 struct unwind_libunwind_ops *
 local_unwind_libunwind_ops = &_unwind_libunwind_ops;
-
-static void unwind__register_ops(struct thread *thread,
-				 struct unwind_libunwind_ops *ops)
-{
-	thread->unwind_libunwind_ops = ops;
-}
-
-int unwind__prepare_access(struct thread *thread)
-{
-	unwind__register_ops(thread, local_unwind_libunwind_ops);
-
-	return thread->unwind_libunwind_ops->prepare_access(thread);
-}
-
-void unwind__flush_access(struct thread *thread)
-{
-	if (thread->unwind_libunwind_ops)
-		thread->unwind_libunwind_ops->flush_access(thread);
-}
-
-void unwind__finish_access(struct thread *thread)
-{
-	if (thread->unwind_libunwind_ops)
-		thread->unwind_libunwind_ops->finish_access(thread);
-}
-
-int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
-			 struct thread *thread,
-			 struct perf_sample *data, int max_stack)
-{
-	if (thread->unwind_libunwind_ops)
-		return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
-	return 0;
-}
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
new file mode 100644
index 000000000000..f86f903ae8a8
--- /dev/null
+++ b/tools/perf/util/unwind-libunwind.c
@@ -0,0 +1,38 @@
+#include "unwind.h"
+#include "thread.h"
+
+struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
+
+static void unwind__register_ops(struct thread *thread,
+			  struct unwind_libunwind_ops *ops)
+{
+	thread->unwind_libunwind_ops = ops;
+}
+
+int unwind__prepare_access(struct thread *thread)
+{
+	unwind__register_ops(thread, local_unwind_libunwind_ops);
+
+	return thread->unwind_libunwind_ops->prepare_access(thread);
+}
+
+void unwind__flush_access(struct thread *thread)
+{
+	if (thread->unwind_libunwind_ops)
+		thread->unwind_libunwind_ops->flush_access(thread);
+}
+
+void unwind__finish_access(struct thread *thread)
+{
+	if (thread->unwind_libunwind_ops)
+		thread->unwind_libunwind_ops->finish_access(thread);
+}
+
+int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
+			 struct thread *thread,
+			 struct perf_sample *data, int max_stack)
+{
+	if (thread->unwind_libunwind_ops)
+		return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
+	return 0;
+}
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 19/24] perf tools: Export normalize_arch() function
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (17 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 18/24] perf tools: Extract common API out of unwind-libunwind-local.c Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 20/24] perf unwind: Check the target platform before assigning unwind methods Arnaldo Carvalho de Melo
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Export normalize_arch() function, so other part of perf can get
normalized form of arch string.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-10-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/common.c | 2 +-
 tools/perf/arch/common.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index e83c8ce24303..fa090a9eaa38 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -102,7 +102,7 @@ static int lookup_triplets(const char *const *triplets, const char *name)
  * Return architecture name in a normalized form.
  * The conversion logic comes from the Makefile.
  */
-static const char *normalize_arch(char *arch)
+const char *normalize_arch(char *arch)
 {
 	if (!strcmp(arch, "x86_64"))
 		return "x86";
diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h
index 7529cfb143ce..6b01c736b7d9 100644
--- a/tools/perf/arch/common.h
+++ b/tools/perf/arch/common.h
@@ -6,5 +6,6 @@
 extern const char *objdump_path;
 
 int perf_env__lookup_objdump(struct perf_env *env);
+const char *normalize_arch(char *arch);
 
 #endif /* ARCH_PERF_COMMON_H */
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 20/24] perf unwind: Check the target platform before assigning unwind methods
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (18 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 19/24] perf tools: Export normalize_arch() function Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:04 ` [PATCH 21/24] perf unwind: Change fixed name of libunwind__arch_reg_id to macro Arnaldo Carvalho de Melo
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Currently, 'perf script' uses host unwind methods to parse perf.data
callchain info without taking the target architecture into account, i.e.
assuming the perf.data file was generated on the same machine where the
analysis is being performed. So we get wrong result without any warnings
when unwinding callchains of x86(32-bit) on x86(64-bit) machine.

This patch adds an extra step that checks the target platform before
assigning unwind methods. In later patches in this series, we can use
this info to assign the right unwind methods for supported platforms.

Committer note:

After fixing it to register the local unwinder for live mode tools
('perf trace', 'perf top'), i.e. tools that don't use a perf.data file,
it works as intended and passes the 'perf test unwind' test:

  # perf trace -e nanosleep --call dwarf usleep 1
     0.328 ( 0.058 ms): usleep/11115 nanosleep(rqtp: 0x7fff083fa480) = 0
                                       __nanosleep_nocancel+0x7 (/usr/lib64/libc-2.22.so)
                                       usleep+0x34 (/usr/lib64/libc-2.22.so)
                                       main+0x1eb (/usr/bin/usleep)
                                       __libc_start_main+0xf0 (/usr/lib64/libc-2.22.so)
                                       _start+0x29 (/usr/bin/usleep)
  # perf test 48
  48: Test dwarf unwind         : Ok
  #

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-11-git-send-email-hekuang@huawei.com
[ Fixed exit path for 'live' mode tools, where we need to default to local unwinding ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/thread.c           |  2 +-
 tools/perf/util/unwind-libunwind.c | 25 ++++++++++++++++++++++++-
 tools/perf/util/unwind.h           |  8 +++++---
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 0bf552560a41..f30f9566fddc 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -202,7 +202,7 @@ int thread__insert_map(struct thread *thread, struct map *map)
 {
 	int ret;
 
-	ret = unwind__prepare_access(thread);
+	ret = unwind__prepare_access(thread, map);
 	if (ret)
 		return ret;
 
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index f86f903ae8a8..0086726e00e0 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -1,5 +1,8 @@
 #include "unwind.h"
 #include "thread.h"
+#include "session.h"
+#include "debug.h"
+#include "arch/common.h"
 
 struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
 
@@ -9,8 +12,28 @@ static void unwind__register_ops(struct thread *thread,
 	thread->unwind_libunwind_ops = ops;
 }
 
-int unwind__prepare_access(struct thread *thread)
+int unwind__prepare_access(struct thread *thread, struct map *map)
 {
+	const char *arch;
+	enum dso_type dso_type;
+
+	if (thread->addr_space) {
+		pr_debug("unwind: thread map already set, dso=%s\n",
+			 map->dso->name);
+		return 0;
+	}
+
+	/* env->arch is NULL for live-mode (i.e. perf top) */
+	if (!thread->mg->machine->env || !thread->mg->machine->env->arch)
+		goto out_register;
+
+	dso_type = dso__type(map->dso, thread->mg->machine);
+	if (dso_type == DSO__TYPE_UNKNOWN)
+		return 0;
+
+	arch = normalize_arch(thread->mg->machine->env->arch);
+	pr_debug("unwind: target platform=%s\n", arch);
+out_register:
 	unwind__register_ops(thread, local_unwind_libunwind_ops);
 
 	return thread->unwind_libunwind_ops->prepare_access(thread);
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index bbd73d9bea45..bf9f5937caee 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -30,11 +30,12 @@ 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);
+int unwind__prepare_access(struct thread *thread, struct map *map);
 void unwind__flush_access(struct thread *thread);
 void unwind__finish_access(struct thread *thread);
 #else
-static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
+static inline int unwind__prepare_access(struct thread *thread __maybe_unused,
+					 struct map *map __maybe_unused)
 {
 	return 0;
 }
@@ -53,7 +54,8 @@ 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 thread *thread __maybe_unused,
+					 struct map *map __maybe_unused)
 {
 	return 0;
 }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 21/24] perf unwind: Change fixed name of libunwind__arch_reg_id to macro
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (19 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 20/24] perf unwind: Check the target platform before assigning unwind methods Arnaldo Carvalho de Melo
@ 2016-06-07 20:04 ` Arnaldo Carvalho de Melo
  2016-06-07 20:05 ` [PATCH 22/24] perf unwind: Introduce flag to separate local/remote unwind compilation Arnaldo Carvalho de Melo
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:04 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

For local libunwind, it uses the fixed methods to convert register id
according to the host platform, but in remote libunwind, this convert
function should be the one for remote architecture. This patch changes
the fixed name to macro and code for each remote platform can be
compiled indivadually.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-12-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/unwind-libunwind-local.c | 2 +-
 tools/perf/util/unwind.h                 | 5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 9c70486c5c6a..631b40d94643 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -508,7 +508,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as,
 		return 0;
 	}
 
-	id = libunwind__arch_reg_id(regnum);
+	id = LIBUNWIND__ARCH_REG_ID(regnum);
 	if (id < 0)
 		return -EINVAL;
 
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index bf9f5937caee..b07466240346 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -29,7 +29,10 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 			struct perf_sample *data, int max_stack);
 /* libunwind specific */
 #ifdef HAVE_LIBUNWIND_SUPPORT
-int libunwind__arch_reg_id(int regnum);
+#ifndef LIBUNWIND__ARCH_REG_ID
+#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arch_reg_id(regnum)
+#endif
+int LIBUNWIND__ARCH_REG_ID(int regnum);
 int unwind__prepare_access(struct thread *thread, struct map *map);
 void unwind__flush_access(struct thread *thread);
 void unwind__finish_access(struct thread *thread);
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 22/24] perf unwind: Introduce flag to separate local/remote unwind compilation
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (20 preceding siblings ...)
  2016-06-07 20:04 ` [PATCH 21/24] perf unwind: Change fixed name of libunwind__arch_reg_id to macro Arnaldo Carvalho de Melo
@ 2016-06-07 20:05 ` Arnaldo Carvalho de Melo
  2016-06-07 20:05 ` [PATCH 23/24] perf callchain: Support x86 target platform Arnaldo Carvalho de Melo
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:05 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

This is a preparation for including unwind-libunwind-local.c in other
files for remote libunwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-13-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/unwind-libunwind-local.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 631b40d94643..01c2e86977f4 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -22,8 +22,10 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <linux/list.h>
+#ifndef REMOTE_UNWIND_LIBUNWIND
 #include <libunwind.h>
 #include <libunwind-ptrace.h>
+#endif
 #include "callchain.h"
 #include "thread.h"
 #include "session.h"
@@ -689,5 +691,7 @@ _unwind_libunwind_ops = {
 	.get_entries    = _unwind__get_entries,
 };
 
+#ifndef REMOTE_UNWIND_LIBUNWIND
 struct unwind_libunwind_ops *
 local_unwind_libunwind_ops = &_unwind_libunwind_ops;
+#endif
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 23/24] perf callchain: Support x86 target platform
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (21 preceding siblings ...)
  2016-06-07 20:05 ` [PATCH 22/24] perf unwind: Introduce flag to separate local/remote unwind compilation Arnaldo Carvalho de Melo
@ 2016-06-07 20:05 ` Arnaldo Carvalho de Melo
  2016-06-07 20:05 ` [PATCH 24/24] perf callchain: Support aarch64 cross-platform Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:05 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Support x86(32-bit) cross platform callchain unwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-14-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/util/unwind-libunwind.c |  6 +++--
 tools/perf/config/Makefile                  |  8 +++++++
 tools/perf/util/Build                       |  1 +
 tools/perf/util/libunwind/x86_32.c          | 37 +++++++++++++++++++++++++++++
 tools/perf/util/unwind-libunwind.c          | 15 ++++++++++--
 5 files changed, 63 insertions(+), 4 deletions(-)
 create mode 100644 tools/perf/util/libunwind/x86_32.c

diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c
index db25e93d989c..4f16661cbdbb 100644
--- a/tools/perf/arch/x86/util/unwind-libunwind.c
+++ b/tools/perf/arch/x86/util/unwind-libunwind.c
@@ -1,12 +1,14 @@
 
+#ifndef REMOTE_UNWIND_LIBUNWIND
 #include <errno.h>
 #include <libunwind.h>
 #include "perf_regs.h"
 #include "../../util/unwind.h"
 #include "../../util/debug.h"
+#endif
 
 #ifdef HAVE_ARCH_X86_64_SUPPORT
-int libunwind__arch_reg_id(int regnum)
+int LIBUNWIND__ARCH_REG_ID(int regnum)
 {
 	int id;
 
@@ -70,7 +72,7 @@ int libunwind__arch_reg_id(int regnum)
 	return id;
 }
 #else
-int libunwind__arch_reg_id(int regnum)
+int LIBUNWIND__ARCH_REG_ID(int regnum)
 {
 	int id;
 
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 3918687e7816..34999fb19358 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -354,6 +354,14 @@ endif
 
 ifndef NO_LIBUNWIND
   have_libunwind :=
+
+  ifeq ($(feature-libunwind-x86), 1)
+    $(call detected,CONFIG_LIBUNWIND_X86)
+    CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
+    LDFLAGS += -lunwind-x86
+    have_libunwind = 1
+  endif
+
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
     NO_LOCAL_LIBUNWIND := 1
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 004fb1d1d0ad..7746e0932768 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -101,6 +101,7 @@ libperf-$(CONFIG_DWARF) += dwarf-aux.o
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
 libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
+libperf-$(CONFIG_LIBUNWIND_X86)      += libunwind/x86_32.o
 
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
diff --git a/tools/perf/util/libunwind/x86_32.c b/tools/perf/util/libunwind/x86_32.c
new file mode 100644
index 000000000000..d98c17e19a2b
--- /dev/null
+++ b/tools/perf/util/libunwind/x86_32.c
@@ -0,0 +1,37 @@
+/*
+ * This file setups defines to compile arch specific binary from the
+ * generic one.
+ *
+ * The function 'LIBUNWIND__ARCH_REG_ID' name is set according to arch
+ * name and the defination of this function is included directly from
+ * 'arch/x86/util/unwind-libunwind.c', to make sure that this function
+ * is defined no matter what arch the host is.
+ *
+ * Finally, the arch specific unwind methods are exported which will
+ * be assigned to each x86 thread.
+ */
+
+#define REMOTE_UNWIND_LIBUNWIND
+#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__x86_reg_id(regnum)
+
+#include "unwind.h"
+#include "debug.h"
+#include "libunwind-x86.h"
+#include <../../../../arch/x86/include/uapi/asm/perf_regs.h>
+
+/* HAVE_ARCH_X86_64_SUPPORT is used in'arch/x86/util/unwind-libunwind.c'
+ * for x86_32, we undef it to compile code for x86_32 only.
+ */
+#undef HAVE_ARCH_X86_64_SUPPORT
+#include "../../arch/x86/util/unwind-libunwind.c"
+
+/* Explicitly define NO_LIBUNWIND_DEBUG_FRAME, because non-ARM has no
+ * dwarf_find_debug_frame() function.
+ */
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
+#define NO_LIBUNWIND_DEBUG_FRAME
+#endif
+#include "util/unwind-libunwind-local.c"
+
+struct unwind_libunwind_ops *
+x86_32_unwind_libunwind_ops = &_unwind_libunwind_ops;
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 0086726e00e0..e65515aa61d9 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -5,6 +5,7 @@
 #include "arch/common.h"
 
 struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
+struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops;
 
 static void unwind__register_ops(struct thread *thread,
 			  struct unwind_libunwind_ops *ops)
@@ -16,6 +17,7 @@ int unwind__prepare_access(struct thread *thread, struct map *map)
 {
 	const char *arch;
 	enum dso_type dso_type;
+	struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
 
 	if (thread->addr_space) {
 		pr_debug("unwind: thread map already set, dso=%s\n",
@@ -32,9 +34,18 @@ int unwind__prepare_access(struct thread *thread, struct map *map)
 		return 0;
 
 	arch = normalize_arch(thread->mg->machine->env->arch);
-	pr_debug("unwind: target platform=%s\n", arch);
+
+	if (!strcmp(arch, "x86")) {
+		if (dso_type != DSO__TYPE_64BIT)
+			ops = x86_32_unwind_libunwind_ops;
+	}
+
+	if (!ops) {
+		pr_err("unwind: target platform=%s is not supported\n", arch);
+		return -1;
+	}
 out_register:
-	unwind__register_ops(thread, local_unwind_libunwind_ops);
+	unwind__register_ops(thread, ops);
 
 	return thread->unwind_libunwind_ops->prepare_access(thread);
 }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 24/24] perf callchain: Support aarch64 cross-platform
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (22 preceding siblings ...)
  2016-06-07 20:05 ` [PATCH 23/24] perf callchain: Support x86 target platform Arnaldo Carvalho de Melo
@ 2016-06-07 20:05 ` Arnaldo Carvalho de Melo
  2016-06-07 23:10 ` [GIT PULL 00/24] perf/core improvements and fixes Taeung Song
  2016-06-08  7:43 ` Ingo Molnar
  25 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-07 20:05 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, He Kuang, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, David Ahern, Ekaterina Tumanova, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Namhyung Kim, Pekka Enberg,
	Peter Zijlstra, Stephane Eranian, Sukadev Bhattiprolu, Wang Nan,
	Arnaldo Carvalho de Melo

From: He Kuang <hekuang@huawei.com>

Support aarch64 cross platform callchain unwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1464924803-22214-15-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/arm64/util/unwind-libunwind.c |  4 ++-
 tools/perf/config/Makefile                    | 12 +++++++++
 tools/perf/util/Build                         |  1 +
 tools/perf/util/libunwind/arm64.c             | 35 +++++++++++++++++++++++++++
 tools/perf/util/unwind-libunwind.c            |  4 +++
 5 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/util/libunwind/arm64.c

diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c
index a87afa91a99e..c116b713f7f7 100644
--- a/tools/perf/arch/arm64/util/unwind-libunwind.c
+++ b/tools/perf/arch/arm64/util/unwind-libunwind.c
@@ -1,11 +1,13 @@
 
+#ifndef REMOTE_UNWIND_LIBUNWIND
 #include <errno.h>
 #include <libunwind.h>
 #include "perf_regs.h"
 #include "../../util/unwind.h"
 #include "../../util/debug.h"
+#endif
 
-int libunwind__arch_reg_id(int regnum)
+int LIBUNWIND__ARCH_REG_ID(int regnum)
 {
 	switch (regnum) {
 	case UNW_AARCH64_X0:
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 34999fb19358..47e8f5835fd6 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -362,6 +362,18 @@ ifndef NO_LIBUNWIND
     have_libunwind = 1
   endif
 
+  ifeq ($(feature-libunwind-aarch64), 1)
+    $(call detected,CONFIG_LIBUNWIND_AARCH64)
+    CFLAGS += -DHAVE_LIBUNWIND_AARCH64_SUPPORT
+    LDFLAGS += -lunwind-aarch64
+    have_libunwind = 1
+    $(call feature_check,libunwind-debug-frame-aarch64)
+    ifneq ($(feature-libunwind-debug-frame-aarch64), 1)
+      msg := $(warning No debug_frame support found in libunwind-aarch64);
+      CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME_AARCH64
+    endif
+  endif
+
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
     NO_LOCAL_LIBUNWIND := 1
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 7746e0932768..fced8336e5fd 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -102,6 +102,7 @@ libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind-local.o
 libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
 libperf-$(CONFIG_LIBUNWIND_X86)      += libunwind/x86_32.o
+libperf-$(CONFIG_LIBUNWIND_AARCH64)  += libunwind/arm64.o
 
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
diff --git a/tools/perf/util/libunwind/arm64.c b/tools/perf/util/libunwind/arm64.c
new file mode 100644
index 000000000000..4fb5395669f8
--- /dev/null
+++ b/tools/perf/util/libunwind/arm64.c
@@ -0,0 +1,35 @@
+/*
+ * This file setups defines to compile arch specific binary from the
+ * generic one.
+ *
+ * The function 'LIBUNWIND__ARCH_REG_ID' name is set according to arch
+ * name and the defination of this function is included directly from
+ * 'arch/arm64/util/unwind-libunwind.c', to make sure that this function
+ * is defined no matter what arch the host is.
+ *
+ * Finally, the arch specific unwind methods are exported which will
+ * be assigned to each arm64 thread.
+ */
+
+#define REMOTE_UNWIND_LIBUNWIND
+
+#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arm64_reg_id(regnum)
+
+#include "unwind.h"
+#include "debug.h"
+#include "libunwind-aarch64.h"
+#include <../../../../arch/arm64/include/uapi/asm/perf_regs.h>
+#include "../../arch/arm64/util/unwind-libunwind.c"
+
+/* NO_LIBUNWIND_DEBUG_FRAME is a feature flag for local libunwind,
+ * assign NO_LIBUNWIND_DEBUG_FRAME_AARCH64 to it for compiling arm64
+ * unwind methods.
+ */
+#undef NO_LIBUNWIND_DEBUG_FRAME
+#ifdef NO_LIBUNWIND_DEBUG_FRAME_AARCH64
+#define NO_LIBUNWIND_DEBUG_FRAME
+#endif
+#include "util/unwind-libunwind-local.c"
+
+struct unwind_libunwind_ops *
+arm64_unwind_libunwind_ops = &_unwind_libunwind_ops;
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index e65515aa61d9..854711966cad 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -6,6 +6,7 @@
 
 struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
 struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops;
+struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops;
 
 static void unwind__register_ops(struct thread *thread,
 			  struct unwind_libunwind_ops *ops)
@@ -38,6 +39,9 @@ int unwind__prepare_access(struct thread *thread, struct map *map)
 	if (!strcmp(arch, "x86")) {
 		if (dso_type != DSO__TYPE_64BIT)
 			ops = x86_32_unwind_libunwind_ops;
+	} else if (!strcmp(arch, "arm64") || !strcmp(arch, "arm")) {
+		if (dso_type == DSO__TYPE_64BIT)
+			ops = arm64_unwind_libunwind_ops;
 	}
 
 	if (!ops) {
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [GIT PULL 00/24] perf/core improvements and fixes
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (23 preceding siblings ...)
  2016-06-07 20:05 ` [PATCH 24/24] perf callchain: Support aarch64 cross-platform Arnaldo Carvalho de Melo
@ 2016-06-07 23:10 ` Taeung Song
  2016-06-08 13:09   ` Arnaldo Carvalho de Melo
  2016-06-08  7:43 ` Ingo Molnar
  25 siblings, 1 reply; 28+ messages in thread
From: Taeung Song @ 2016-06-07 23:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Ingo Molnar, linux-kernel, Arnaldo Carvalho de Melo,
	Adrian Hunter, Alexander Shishkin, Andi Kleen, David Ahern,
	Ekaterina Tumanova, He Kuang, Jiri Olsa, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Milian Wolff, Namhyung Kim,
	Pekka Enberg, Peter Zijlstra, pi3orama, Stephane Eranian,
	Sukadev Bhattiprolu, Wang Nan, Zefan Li,
	Arnaldo Carvalho de Melo

Hi, Arnaldo

I found something weird about perf/core branch on your repository.
(I don't know whether it is just my illusion or not)

I can't pull new commits on top of perf-core-for-mingo-20160606
by normal way as below


# git remote show acme
* remote acme
   Fetch URL: git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git


# git log --oneline
edb13ed tools lib bpf: Rename set_private() to set_priv()
be834ff tools lib bpf: Make bpf_program__get_private() use IS_ERR()
...


# git pull acme perf/core
 From git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
  * branch            perf/core  -> FETCH_HEAD
Already up-to-date.


And then nothing changed, I didn't also find new commits
and new tag 'perf-core-for-mingo-20160607'.

However, if using tag perf-core-for-mingo-20160607,
I can get new commits from your repository as below.


# git fetch acme --tags
remote: Counting objects: 4888, done.
remote: Compressing objects: 100% (4800/4800), done.
remote: Total 4888 (delta 266), reused 1212 (delta 59)
Receiving objects: 100% (4888/4888), 21.36 MiB | 3.72 MiB/s, done.
Resolving deltas: 100% (266/266), done.
 From git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
  * [new tag]         perf-core-for-mingo-20160307 -> 
perf-core-for-mingo-20160307
  * [new tag]         perf-core-for-mingo-20160329 -> 
perf-core-for-mingo-20160329
  * [new tag]         perf-core-for-mingo-20160407 -> 
perf-core-for-mingo-20160407
  * [new tag]         perf-core-for-mingo-20160607 -> 
perf-core-for-mingo-20160607
  * [new tag]         perf-ebpf-for-mingo -> perf-ebpf-for-mingo
  * [new tag]         perf-urgent-for-mingo-20160510 -> 
perf-urgent-for-mingo-20160510
  * [new tag]         v2.6.11    -> v2.6.11
  * [new tag]         v2.6.11-tree -> v2.6.11-tree


But there is a strange thing about git branch.
I can't find which branch is that have tag perf-core-for-mingo-20160607 
like below.


# git branch -a --contains perf-core-for-mingo-20160607


As the final outcome, I got new commits on top of 
perf-core-for-mingo-20160606 directly using a tag 
'perf-core-for-mingo-20160607' as below.


# git reset --hard perf-core-for-mingo-20160607
HEAD is now at 057fbfb perf callchain: Support aarch64 cross-platform


But isn't it a problem ?
Just use a tag?


Thanks,
Taeung

On 06/08/2016 05:04 AM, Arnaldo Carvalho de Melo wrote:
> Hi Ingo,
>
> 	Please consider pulling, this is on top of perf-core-for-mingo-20160606,
>
> Thanks,
>
> - Arnaldo
>
> The following changes since commit 7db91f251056f90fec4121f028680ab3153a0f3c:
>
>    perf config: Handle the error when config set is NULL at collect_config() (2016-06-06 17:43:19 -0300)
>
> are available in the git repository at:
>
>    git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160607
>
> for you to fetch changes up to 057fbfb25cde4a368418f3f720cdc31d48800c4d:
>
>    perf callchain: Support aarch64 cross-platform (2016-06-07 15:13:35 -0300)
>
> ----------------------------------------------------------------
> perf/core improvements and fixes:
>
> User visible:
>
> - Support cross unwinding, i.e. collecting '--call-graph dwarf' perf.data files
>    in one machine and then doing analysis in another machine of a different
>    hardware architecture. This enables, for instance, to do:
>
> 	perf record -a --call-graph dwarf
>
>    on a x86-32 or aarch64 system and then do 'perf report' on it on a
>    x86_64 workstation. (He Kuang)
>
> - Fix crash in build_id_cache__kallsyms_path(), recent regression (Wang Nan)
>
> Infrastructure:
>
> - Make tools/lib/bpf use the IS_ERR return facility consistently and also stop
>    using the _get_ term for non-reference count methods (Arnaldo Carvalho de Melo)
>
> - 'perf config' refactorings (Taeung Song)
>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> ----------------------------------------------------------------
> Arnaldo Carvalho de Melo (7):
>        tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private()
>        tools lib bpf: Rename bpf_map__get_name() to bpf_map__name()
>        tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def()
>        tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd()
>        tools lib bpf: Remove _get_ from non-refcount method names
>        tools lib bpf: Make bpf_program__get_private() use IS_ERR()
>        tools lib bpf: Rename set_private() to set_priv()
>
> He Kuang (14):
>        perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check
>        perf unwind: Decouple thread->address_space on libunwind
>        perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind
>        perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map
>        perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS
>        perf unwind: Separate local/remote libunwind config
>        perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c
>        perf tools: Extract common API out of unwind-libunwind-local.c
>        perf tools: Export normalize_arch() function
>        perf unwind: Check the target platform before assigning unwind methods
>        perf unwind: Change fixed name of libunwind__arch_reg_id to macro
>        perf unwind: Introduce flag to separate local/remote unwind compilation
>        perf callchain: Support x86 target platform
>        perf callchain: Support aarch64 cross-platform
>
> Taeung Song (2):
>        perf config: Constructor should free its allocated memory when failing
>        perf config: Use new perf_config_set__init() to initialize config set
>
> Wang Nan (1):
>        perf tools: Fix crash in build_id_cache__kallsyms_path()
>
>   tools/lib/bpf/libbpf.c                        |  60 +--
>   tools/lib/bpf/libbpf.h                        |  25 +-
>   tools/perf/arch/arm/util/Build                |   2 +-
>   tools/perf/arch/arm64/util/Build              |   2 +-
>   tools/perf/arch/arm64/util/unwind-libunwind.c |   4 +-
>   tools/perf/arch/common.c                      |   2 +-
>   tools/perf/arch/common.h                      |   1 +
>   tools/perf/arch/x86/util/Build                |   2 +-
>   tools/perf/arch/x86/util/unwind-libunwind.c   |   6 +-
>   tools/perf/config/Makefile                    |  52 +-
>   tools/perf/util/Build                         |   3 +
>   tools/perf/util/bpf-loader.c                  | 132 +++--
>   tools/perf/util/build-id.c                    |  11 +-
>   tools/perf/util/config.c                      |  51 +-
>   tools/perf/util/libunwind/arm64.c             |  35 ++
>   tools/perf/util/libunwind/x86_32.c            |  37 ++
>   tools/perf/util/machine.c                     |  14 +-
>   tools/perf/util/thread.c                      |  13 +-
>   tools/perf/util/thread.h                      |   9 +-
>   tools/perf/util/unwind-libunwind-local.c      | 697 ++++++++++++++++++++++++++
>   tools/perf/util/unwind-libunwind.c            | 688 ++-----------------------
>   tools/perf/util/unwind.h                      |  22 +-
>   22 files changed, 1056 insertions(+), 812 deletions(-)
>   create mode 100644 tools/perf/util/libunwind/arm64.c
>   create mode 100644 tools/perf/util/libunwind/x86_32.c
>   create mode 100644 tools/perf/util/unwind-libunwind-local.c
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [GIT PULL 00/24] perf/core improvements and fixes
  2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
                   ` (24 preceding siblings ...)
  2016-06-07 23:10 ` [GIT PULL 00/24] perf/core improvements and fixes Taeung Song
@ 2016-06-08  7:43 ` Ingo Molnar
  25 siblings, 0 replies; 28+ messages in thread
From: Ingo Molnar @ 2016-06-08  7:43 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Adrian Hunter, Alexander Shishkin, Andi Kleen,
	David Ahern, Ekaterina Tumanova, He Kuang, Jiri Olsa,
	Josh Poimboeuf, Kan Liang, Masami Hiramatsu, Milian Wolff,
	Namhyung Kim, Pekka Enberg, Peter Zijlstra, pi3orama,
	Stephane Eranian, Sukadev Bhattiprolu, Taeung Song, Wang Nan,
	Zefan Li, Arnaldo Carvalho de Melo


* Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> Hi Ingo,
> 
> 	Please consider pulling, this is on top of perf-core-for-mingo-20160606,
> 
> Thanks,
> 
> - Arnaldo
> 
> The following changes since commit 7db91f251056f90fec4121f028680ab3153a0f3c:
> 
>   perf config: Handle the error when config set is NULL at collect_config() (2016-06-06 17:43:19 -0300)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160607
> 
> for you to fetch changes up to 057fbfb25cde4a368418f3f720cdc31d48800c4d:
> 
>   perf callchain: Support aarch64 cross-platform (2016-06-07 15:13:35 -0300)
> 
> ----------------------------------------------------------------
> perf/core improvements and fixes:
> 
> User visible:
> 
> - Support cross unwinding, i.e. collecting '--call-graph dwarf' perf.data files
>   in one machine and then doing analysis in another machine of a different
>   hardware architecture. This enables, for instance, to do:
> 
> 	perf record -a --call-graph dwarf
> 
>   on a x86-32 or aarch64 system and then do 'perf report' on it on a
>   x86_64 workstation. (He Kuang)
> 
> - Fix crash in build_id_cache__kallsyms_path(), recent regression (Wang Nan)
> 
> Infrastructure:
> 
> - Make tools/lib/bpf use the IS_ERR return facility consistently and also stop
>   using the _get_ term for non-reference count methods (Arnaldo Carvalho de Melo)
> 
> - 'perf config' refactorings (Taeung Song)
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> ----------------------------------------------------------------
> Arnaldo Carvalho de Melo (7):
>       tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private()
>       tools lib bpf: Rename bpf_map__get_name() to bpf_map__name()
>       tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def()
>       tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd()
>       tools lib bpf: Remove _get_ from non-refcount method names
>       tools lib bpf: Make bpf_program__get_private() use IS_ERR()
>       tools lib bpf: Rename set_private() to set_priv()
> 
> He Kuang (14):
>       perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check
>       perf unwind: Decouple thread->address_space on libunwind
>       perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind
>       perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map
>       perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS
>       perf unwind: Separate local/remote libunwind config
>       perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c
>       perf tools: Extract common API out of unwind-libunwind-local.c
>       perf tools: Export normalize_arch() function
>       perf unwind: Check the target platform before assigning unwind methods
>       perf unwind: Change fixed name of libunwind__arch_reg_id to macro
>       perf unwind: Introduce flag to separate local/remote unwind compilation
>       perf callchain: Support x86 target platform
>       perf callchain: Support aarch64 cross-platform
> 
> Taeung Song (2):
>       perf config: Constructor should free its allocated memory when failing
>       perf config: Use new perf_config_set__init() to initialize config set
> 
> Wang Nan (1):
>       perf tools: Fix crash in build_id_cache__kallsyms_path()
> 
>  tools/lib/bpf/libbpf.c                        |  60 +--
>  tools/lib/bpf/libbpf.h                        |  25 +-
>  tools/perf/arch/arm/util/Build                |   2 +-
>  tools/perf/arch/arm64/util/Build              |   2 +-
>  tools/perf/arch/arm64/util/unwind-libunwind.c |   4 +-
>  tools/perf/arch/common.c                      |   2 +-
>  tools/perf/arch/common.h                      |   1 +
>  tools/perf/arch/x86/util/Build                |   2 +-
>  tools/perf/arch/x86/util/unwind-libunwind.c   |   6 +-
>  tools/perf/config/Makefile                    |  52 +-
>  tools/perf/util/Build                         |   3 +
>  tools/perf/util/bpf-loader.c                  | 132 +++--
>  tools/perf/util/build-id.c                    |  11 +-
>  tools/perf/util/config.c                      |  51 +-
>  tools/perf/util/libunwind/arm64.c             |  35 ++
>  tools/perf/util/libunwind/x86_32.c            |  37 ++
>  tools/perf/util/machine.c                     |  14 +-
>  tools/perf/util/thread.c                      |  13 +-
>  tools/perf/util/thread.h                      |   9 +-
>  tools/perf/util/unwind-libunwind-local.c      | 697 ++++++++++++++++++++++++++
>  tools/perf/util/unwind-libunwind.c            | 688 ++-----------------------
>  tools/perf/util/unwind.h                      |  22 +-
>  22 files changed, 1056 insertions(+), 812 deletions(-)
>  create mode 100644 tools/perf/util/libunwind/arm64.c
>  create mode 100644 tools/perf/util/libunwind/x86_32.c
>  create mode 100644 tools/perf/util/unwind-libunwind-local.c

Pulled, thanks a lot Arnaldo!

	Ingo

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [GIT PULL 00/24] perf/core improvements and fixes
  2016-06-07 23:10 ` [GIT PULL 00/24] perf/core improvements and fixes Taeung Song
@ 2016-06-08 13:09   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 28+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-06-08 13:09 UTC (permalink / raw)
  To: Taeung Song
  Cc: Arnaldo Carvalho de Melo, Ingo Molnar, linux-kernel,
	Adrian Hunter, Alexander Shishkin, Andi Kleen, David Ahern,
	Ekaterina Tumanova, He Kuang, Jiri Olsa, Josh Poimboeuf,
	Kan Liang, Masami Hiramatsu, Milian Wolff, Namhyung Kim,
	Pekka Enberg, Peter Zijlstra, pi3orama, Stephane Eranian,
	Sukadev Bhattiprolu, Wang Nan, Zefan Li,
	Arnaldo Carvalho de Melo

Em Wed, Jun 08, 2016 at 08:10:50AM +0900, Taeung Song escreveu:
> I found something weird about perf/core branch on your repository.
> (I don't know whether it is just my illusion or not)
> 
> I can't pull new commits on top of perf-core-for-mingo-20160606
> by normal way as below

I forgot to push perf/core, having pushed just
perf-core-for-mingo-20160607, which is enough for Ingo to pull what I
sent to him, but not for you to get if you use perf/core, as usual,
instead of perf-core-for-mingo-20160607.

I pushed perf/core now, please update your local repo and all should be
ok now.

- Arnaldo

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2016-06-08 13:10 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-07 20:04 [GIT PULL 00/24] perf/core improvements and fixes Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 01/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 02/24] tools lib bpf: Rename bpf_map__get_name() to bpf_map__name() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 03/24] tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 04/24] tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 05/24] tools lib bpf: Remove _get_ from non-refcount method names Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 06/24] tools lib bpf: Make bpf_program__get_private() use IS_ERR() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 07/24] tools lib bpf: Rename set_private() to set_priv() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 08/24] perf tools: Fix crash in build_id_cache__kallsyms_path() Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 09/24] perf config: Constructor should free its allocated memory when failing Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 10/24] perf config: Use new perf_config_set__init() to initialize config set Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 11/24] perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 12/24] perf unwind: Decouple thread->address_space on libunwind Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 13/24] perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 14/24] perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 15/24] perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 16/24] perf unwind: Separate local/remote libunwind config Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 17/24] perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 18/24] perf tools: Extract common API out of unwind-libunwind-local.c Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 19/24] perf tools: Export normalize_arch() function Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 20/24] perf unwind: Check the target platform before assigning unwind methods Arnaldo Carvalho de Melo
2016-06-07 20:04 ` [PATCH 21/24] perf unwind: Change fixed name of libunwind__arch_reg_id to macro Arnaldo Carvalho de Melo
2016-06-07 20:05 ` [PATCH 22/24] perf unwind: Introduce flag to separate local/remote unwind compilation Arnaldo Carvalho de Melo
2016-06-07 20:05 ` [PATCH 23/24] perf callchain: Support x86 target platform Arnaldo Carvalho de Melo
2016-06-07 20:05 ` [PATCH 24/24] perf callchain: Support aarch64 cross-platform Arnaldo Carvalho de Melo
2016-06-07 23:10 ` [GIT PULL 00/24] perf/core improvements and fixes Taeung Song
2016-06-08 13:09   ` Arnaldo Carvalho de Melo
2016-06-08  7:43 ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).