diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-06-08 09:34:15 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-06-08 09:34:15 +0200 |
commit | b8ab92201a64886fd3d8078fe46e51f658379823 (patch) | |
tree | 120b6304d64e732b65ecbfccbeb14587bac1063c /tools | |
parent | aa3a655b159f11b1afe0dcdac5fb5b172f02b778 (diff) | |
parent | 057fbfb25cde4a368418f3f720cdc31d48800c4d (diff) |
Merge tag 'perf-core-for-mingo-20160607' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
User visible changes:
- 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 changes:
- 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>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lib/bpf/libbpf.c | 60 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.h | 25 | ||||
-rw-r--r-- | tools/perf/arch/arm/util/Build | 2 | ||||
-rw-r--r-- | tools/perf/arch/arm64/util/Build | 2 | ||||
-rw-r--r-- | tools/perf/arch/arm64/util/unwind-libunwind.c | 4 | ||||
-rw-r--r-- | tools/perf/arch/common.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/common.h | 1 | ||||
-rw-r--r-- | tools/perf/arch/x86/util/Build | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/util/unwind-libunwind.c | 6 | ||||
-rw-r--r-- | tools/perf/config/Makefile | 52 | ||||
-rw-r--r-- | tools/perf/util/Build | 3 | ||||
-rw-r--r-- | tools/perf/util/bpf-loader.c | 132 | ||||
-rw-r--r-- | tools/perf/util/build-id.c | 11 | ||||
-rw-r--r-- | tools/perf/util/config.c | 51 | ||||
-rw-r--r-- | tools/perf/util/libunwind/arm64.c | 35 | ||||
-rw-r--r-- | tools/perf/util/libunwind/x86_32.c | 37 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 14 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 13 | ||||
-rw-r--r-- | tools/perf/util/thread.h | 9 | ||||
-rw-r--r-- | tools/perf/util/unwind-libunwind-local.c | 697 | ||||
-rw-r--r-- | tools/perf/util/unwind-libunwind.c | 688 | ||||
-rw-r--r-- | tools/perf/util/unwind.h | 22 |
22 files changed, 1056 insertions, 812 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 7e543c3102d4..462e526a4465 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 * @@ -1224,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); @@ -1236,10 +1229,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) @@ -1311,32 +1303,23 @@ 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; } -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__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, - 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; @@ -1351,14 +1334,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 * @@ -1389,7 +1367,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 a51594c7b518..722f46b2d553 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) \ @@ -78,11 +78,10 @@ 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); -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); @@ -171,7 +170,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); @@ -180,13 +179,13 @@ 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__get_def(struct bpf_map *map, struct bpf_map_def *pdef); -const char *bpf_map__get_name(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); 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); +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/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/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/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 */ 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/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 5ad0255f8756..098874b99981 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -73,17 +73,25 @@ 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) # 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 @@ -351,10 +359,40 @@ ifeq ($(ARCH),powerpc) 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 + + 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 + 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 @@ -392,7 +430,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) @@ -403,8 +441,12 @@ 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) endif diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 8c6c8a0ca642..fced8336e5fd 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -99,7 +99,10 @@ libperf-$(CONFIG_DWARF) += probe-finder.o 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_LIBUNWIND_AARCH64) += libunwind/arm64.o libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 493307d1414c..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; @@ -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; } @@ -897,15 +894,12 @@ 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; - const char *map_name; - int err; + const char *map_name = bpf_map__name(map); + struct bpf_map_priv *priv = bpf_map__priv(map); - 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) { @@ -916,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; } @@ -948,30 +942,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; - int err; + const char *map_name = bpf_map__name(map); + const struct bpf_map_def *def = bpf_map__def(map); - map_name = bpf_map__get_name(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: @@ -1014,12 +1004,10 @@ __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; - int err; + const char *map_name = bpf_map__name(map); - 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", @@ -1027,18 +1015,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; @@ -1087,9 +1075,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; @@ -1099,8 +1086,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; @@ -1111,7 +1098,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; } @@ -1147,7 +1134,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; @@ -1204,14 +1191,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; @@ -1231,7 +1218,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; @@ -1261,15 +1248,12 @@ 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; - struct bpf_map_priv *priv; + const 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); - - 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; } @@ -1278,29 +1262,29 @@ 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; } - 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; } 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: @@ -1410,7 +1394,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) { @@ -1475,9 +1459,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) { @@ -1489,10 +1473,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 +1503,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; @@ -1533,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; @@ -1677,7 +1659,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)) { 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; } diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index c73f1c4d1ca9..8749eca3055f 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -643,17 +643,64 @@ static int collect_config(const char *var, const char *value, out_free: free(key); - perf_config_set__delete(set); 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); - perf_config(collect_config, set); + if (perf_config_set__init(set) < 0) { + perf_config_set__delete(set); + set = NULL; + } } return set; 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 @@ +/* |