Skip to contentSkip to conversation

perf/core improvements and fixes

GIT PULL New Arnaldo Carvalho de Melo 3 participants 28 messages Jun 7, 2016 – Jun 8, 2016

Subsystems (4)
lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

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)

----------------------------------------------------------------
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
author maintainer
#1 lore raw

PATCH 1/24 tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_private()

From: Arnaldo Carvalho de Melo <[email protected]>

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.

---
 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(-)
tools/lib/bpf/libbpf.c +2 -7
index 7e543c3102d4..9bba1a907abe 100644
@@ -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 *
tools/lib/bpf/libbpf.h +1 -1
index a51594c7b518..916abf971249 100644
@@ -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
tools/perf/util/bpf-loader.c +9 -14
index 493307d1414c..e9a034e86b91 100644
@@ -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;
Signature · 1 line
2.5.5
author maintainer
#2 lore raw

PATCH 2/24 tools lib bpf: Rename bpf_map__get_name() to bpf_map__name()

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

For consistency, leaving "get" for reference counting.

---
 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(-)
tools/lib/bpf/libbpf.c +2 -4
index 9bba1a907abe..4dc617befd13 100644
@@ -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,
tools/lib/bpf/libbpf.h +1 -1
index 916abf971249..f8fbba4ccef3 100644
@@ -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,
tools/perf/util/bpf-loader.c +6 -12
index e9a034e86b91..c819eb8ba145 100644
@@ -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)
 {
Signature · 1 line
2.5.5
author maintainer
#3 lore raw

PATCH 3/24 tools lib bpf: Use IS_ERR() reporting macros with bpf_map__get_def()

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

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.

---
 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(-)
tools/lib/bpf/libbpf.c +2 -6
index 4dc617befd13..215be67f038b 100644
@@ -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)
tools/lib/bpf/libbpf.h +1 -1
index f8fbba4ccef3..bad5bac58db4 100644
@@ -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 *);
tools/perf/util/bpf-loader.c +24 -28

164 lines not on this page · raw message

Signature · 1 line
2.5.5
author maintainer
#4 lore raw

PATCH 4/24 tools lib bpf: Rename bpf_map__get_fd() to bpf_map__fd()

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

For consistency, leaving "get" for reference counting.

---
 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(-)
tools/lib/bpf/libbpf.c +2 -5
index 215be67f038b..57924db2d16f 100644
@@ -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)
tools/lib/bpf/libbpf.h +1 -1
index bad5bac58db4..cb838d0ea753 100644
@@ -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);
 
tools/perf/util/bpf-loader.c +1 -1
index 73c1e7cf8760..12e6ef4c2f9e 100644
@@ -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;
Signature · 1 line
2.5.5
author maintainer
#5 lore raw

PATCH 5/24 tools lib bpf: Remove _get_ from non-refcount method names

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

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 <[email protected]>

---
 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(-)
tools/lib/bpf/libbpf.c +5 -11
index 57924db2d16f..0412182fb365 100644
@@ -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;
 
tools/lib/bpf/libbpf.h +3 -3
index cb838d0ea753..ea65775e8302 100644
@@ -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);
tools/perf/util/bpf-loader.c +2 -2
index 12e6ef4c2f9e..c19010e6cefb 100644
@@ -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)) {
Signature · 1 line
2.5.5
author maintainer
#6 lore raw

PATCH 6/24 tools lib bpf: Make bpf_program__get_private() use IS_ERR()

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

For consistency with bpf_map__priv() and elsewhere.

---
 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(-)
tools/lib/bpf/libbpf.c +2 -3
index 0412182fb365..7eb7fb26e999 100644
@@ -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)
tools/lib/bpf/libbpf.h +1 -2
index ea65775e8302..372cecbde207 100644
@@ -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);
 
tools/perf/util/bpf-loader.c +12 -15
index c19010e6cefb..1907d5313960 100644
@@ -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;
 		}
Signature · 1 line
2.5.5
author maintainer
#7 lore raw

PATCH 7/24 tools lib bpf: Rename set_private() to set_priv()

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

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

---
 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(-)
tools/lib/bpf/libbpf.c +4 -5
index 7eb7fb26e999..462e526a4465 100644
@@ -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;
tools/lib/bpf/libbpf.h +4 -4
index 372cecbde207..722f46b2d553 100644
@@ -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
tools/perf/util/bpf-loader.c +3 -3
index 1907d5313960..dcc8845881ae 100644
@@ -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;
Signature · 1 line
2.5.5
author maintainer
#8 lore raw

PATCH 8/24 perf tools: Fix crash in build_id_cache__kallsyms_path()

In reply to Arnaldo Carvalho de Melo

From: Wang Nan <[email protected]>

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.

Cc Masami Hiramatsu <[email protected]>
Cc Zefan Li <[email protected]>
Fixes 01412261d994 ("perf buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid")
---
 tools/perf/util/build-id.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
tools/perf/util/build-id.c +4 -7
index 67f986c8c378..20aef90bf194 100644
@@ -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;
 	}
Signature · 1 line
2.5.5
author maintainer
#9 lore raw

PATCH 9/24 perf config: Constructor should free its allocated memory when failing

In reply to Arnaldo Carvalho de Melo

From: Taeung Song <[email protected]>

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().

---
 tools/perf/util/config.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
tools/perf/util/config.c +4 -2
index c73f1c4d1ca9..e086f593a2aa 100644
@@ -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;
Signature · 1 line
2.5.5
author maintainer
#10 lore raw

PATCH 10/24 perf config: Use new perf_config_set__init() to initialize config set

In reply to Arnaldo Carvalho de Melo

From: Taeung Song <[email protected]>

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.

---
 tools/perf/util/config.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)
tools/perf/util/config.c +46 -1
index e086f593a2aa..8749eca3055f 100644
@@ -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;
 		}
Signature · 1 line
2.5.5
author maintainer
#11 lore raw

PATCH 11/24 perf unwind: Use LIBUNWIND_DIR for remote libunwind feature check

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/config/Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)
tools/perf/config/Makefile +9 -0
index 1e46277286c2..6f9f566a757c 100644
@@ -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)
 
Signature · 1 line
2.5.5
author maintainer
#12 lore raw

PATCH 12/24 perf unwind: Decouple thread->address_space on libunwind

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/util/thread.h | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/util/thread.h +1 -4
index 08fcb14cf637..4c9f0aa11f1f 100644
@@ -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
 };
 
Signature · 1 line
2.5.5
author maintainer
#13 lore raw

PATCH 13/24 perf unwind: Introduce 'struct unwind_libunwind_ops' for local unwind

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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(-)
tools/perf/util/thread.h +3 -1
index 4c9f0aa11f1f..07ffb18221ab 100644
@@ -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
 };
 
tools/perf/util/unwind-libunwind.c +49 -4

80 lines not on this page · raw message

tools/perf/util/unwind.h +9 -0
index 12790cf94618..bbd73d9bea45 100644
@@ -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,
Signature · 1 line
2.5.5
author maintainer
#14 lore raw

PATCH 14/24 perf unwind: Move unwind__prepare_access from thread_new into thread__insert_map

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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(-)
tools/perf/util/machine.c +12 -2
index 205d27017361..9d931f5d47d0 100644
@@ -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:
tools/perf/util/thread.c +9 -4
index ada58e6070bf..0bf552560a41 100644
@@ -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,
tools/perf/util/thread.h +1 -1
index 07ffb18221ab..99263cb6e6b6 100644
@@ -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);
 
Signature · 1 line
2.5.5
author maintainer
#15 lore raw

PATCH 15/24 perf unwind: Don't mix LIBUNWIND_LIBS into LIBUNWIND_LDFLAGS

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/config/Makefile | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
tools/perf/config/Makefile +3 -4
index 6f9f566a757c..118df2d04b08 100644
@@ -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
Signature · 1 line
2.5.5
author maintainer
#16 lore raw

PATCH 16/24 perf unwind: Separate local/remote libunwind config

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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(-)
tools/perf/arch/arm/util/Build +1 -1
index d22e3d07de3d..f98da17357c0 100644
@@ -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
tools/perf/arch/arm64/util/Build +1 -1
index e58123a8912b..02f41dba4f4f 100644
@@ -1,2 +1,2 @@
 libperf-$(CONFIG_DWARF)     += dwarf-regs.o
-libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o
+libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
tools/perf/arch/x86/util/Build +1 -1
index 4cd8a16b1b7b..f95e6f46ef0d 100644
@@ -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
tools/perf/config/Makefile +17 -3
index 118df2d04b08..3918687e7816 100644
@@ -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
Signature · 1 line
2.5.5
author maintainer
#17 lore raw

PATCH 17/24 perf unwind: Rename unwind-libunwind.c to unwind-libunwind-local.c

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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
tools/perf/util/Build +1 -1
index 8c6c8a0ca642..5e23d85d2d69 100644
@@ -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
 
tools/perf/util/unwind-libunwind-local.c new file +727 -0

727 lines not on this page · raw message

tools/perf/util/unwind-libunwind.c deleted +0 -727

727 lines not on this page · raw message

Signature · 1 line
2.5.5
author maintainer
#18 lore raw

PATCH 18/24 perf tools: Extract common API out of unwind-libunwind-local.c

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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
tools/perf/util/Build +1 -0
index 5e23d85d2d69..004fb1d1d0ad 100644
@@ -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
 
tools/perf/util/unwind-libunwind-local.c +0 -34
index b0c5db1333f9..9c70486c5c6a 100644
@@ -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;
-}
tools/perf/util/unwind-libunwind.c new file +38 -0
new file mode 100644
index 000000000000..f86f903ae8a8
@@ -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;
+}
Signature · 1 line
2.5.5
author maintainer
#19 lore raw

PATCH 19/24 perf tools: Export normalize_arch() function

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/arch/common.c | 2 +-
 tools/perf/arch/common.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
tools/perf/arch/common.c +1 -1
index e83c8ce24303..fa090a9eaa38 100644
@@ -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";
tools/perf/arch/common.h +1 -0
index 7529cfb143ce..6b01c736b7d9 100644
@@ -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 */
Signature · 1 line
2.5.5
author maintainer
#20 lore raw

PATCH 20/24 perf unwind: Check the target platform before assigning unwind methods

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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
  #
Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
[ Fixed exit path for 'live' mode tools, where we need to default to local unwinding ]
---
 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(-)
tools/perf/util/thread.c +1 -1
index 0bf552560a41..f30f9566fddc 100644
@@ -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;
 
tools/perf/util/unwind-libunwind.c +24 -1
index f86f903ae8a8..0086726e00e0 100644
@@ -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);
tools/perf/util/unwind.h +5 -3
index bbd73d9bea45..bf9f5937caee 100644
@@ -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;
 }
Signature · 1 line
2.5.5
author maintainer
#21 lore raw

PATCH 21/24 perf unwind: Change fixed name of libunwind__arch_reg_id to macro

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/util/unwind-libunwind-local.c | 2 +-
 tools/perf/util/unwind.h                 | 5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)
tools/perf/util/unwind-libunwind-local.c +1 -1
index 9c70486c5c6a..631b40d94643 100644
@@ -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;
 
tools/perf/util/unwind.h +4 -1
index bf9f5937caee..b07466240346 100644
@@ -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);
Signature · 1 line
2.5.5
author maintainer
#22 lore raw

PATCH 22/24 perf unwind: Introduce flag to separate local/remote unwind compilation

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 tools/perf/util/unwind-libunwind-local.c | 4 ++++
 1 file changed, 4 insertions(+)
tools/perf/util/unwind-libunwind-local.c +4 -0
index 631b40d94643..01c2e86977f4 100644
@@ -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
Signature · 1 line
2.5.5
author maintainer
#23 lore raw

PATCH 23/24 perf callchain: Support x86 target platform

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

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

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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
tools/perf/arch/x86/util/unwind-libunwind.c +4 -2
index db25e93d989c..4f16661cbdbb 100644
@@ -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;
 
tools/perf/config/Makefile +8 -0
index 3918687e7816..34999fb19358 100644
@@ -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
tools/perf/util/Build +1 -0
index 004fb1d1d0ad..7746e0932768 100644
@@ -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
 
tools/perf/util/libunwind/x86_32.c new file +37 -0
new file mode 100644
index 000000000000..d98c17e19a2b
@@ -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;
tools/perf/util/unwind-libunwind.c +13 -2
index 0086726e00e0..e65515aa61d9 100644
@@ -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);
 }
Signature · 1 line
2.5.5
author maintainer
#24 lore raw

PATCH 24/24 perf callchain: Support aarch64 cross-platform

In reply to Arnaldo Carvalho de Melo

From: He Kuang <[email protected]>

Support aarch64 cross platform callchain unwind.

Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Ekaterina Tumanova <[email protected]>
Cc Josh Poimboeuf <[email protected]>
Cc Kan Liang <[email protected]>
Cc Masami Hiramatsu <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Wang Nan <[email protected]>
---
 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
tools/perf/arch/arm64/util/unwind-libunwind.c +3 -1
index a87afa91a99e..c116b713f7f7 100644
@@ -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:
tools/perf/config/Makefile +12 -0
index 34999fb19358..47e8f5835fd6 100644
@@ -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
tools/perf/util/Build +1 -0
index 7746e0932768..fced8336e5fd 100644
@@ -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
 
tools/perf/util/libunwind/arm64.c new file +35 -0
new file mode 100644
index 000000000000..4fb5395669f8
@@ -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;
tools/perf/util/unwind-libunwind.c +4 -0
index e65515aa61d9..854711966cad 100644
@@ -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) {
Signature · 1 line
2.5.5
#25 lore raw
In reply to 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

Quoted 105 lines · 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)

----------------------------------------------------------------
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

author maintainer
#26 lore raw

Em Wed, Jun 08, 2016 at 08:10:50AM +0900, Taeung Song escreveu:

Quoted 5 lines

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

#27 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 96 lines · 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)

----------------------------------------------------------------
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 +-
Quoted 8 lines
 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