Commit d7cb3a50 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo-4.11-20170201' of...

Merge tag 'perf-core-for-mingo-4.11-20170201' 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:

New features:

- Allow configuring a 'perf ftrace' default --tracer (Taeung Song)

Infrastructure changes:

- Sync tools/arch/{powerpc,arm}/include/uapi/asm/kvm.h and
       tools/arch/x86/include/asm/cpufeatures.h (Ingo Molnar)

- Add BPF program file system pinning APIs and respective
  'perf test' entry (Joe Stringer)

- Make tools tree support 'make -s' (Josh Poimboeuf)

- Reference count maps in callchains, fixing SEGFAULT when
  referencing maps after it is freed (Krister Johansen)

- Create for_each_event trace points iterator (Taeung Song)

- Do not consider an error not to have any perfconfig file
  (Arnaldo Carvalho de Melo

- Propagate perf_config() errors (Arnaldo Carvalho de Melo)
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 5443624b b05d1093
...@@ -87,10 +87,12 @@ endif ...@@ -87,10 +87,12 @@ endif
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),) ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
quiet=silent_ quiet=silent_
tools_silent=s
endif endif
else # make-3.8x else # make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),) ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
quiet=silent_ quiet=silent_
tools_silent=-s
endif endif
endif endif
...@@ -1607,11 +1609,11 @@ image_name: ...@@ -1607,11 +1609,11 @@ image_name:
# Clear a bunch of variables before executing the submake # Clear a bunch of variables before executing the submake
tools/: FORCE tools/: FORCE
$(Q)mkdir -p $(objtree)/tools $(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/
tools/%: FORCE tools/%: FORCE
$(Q)mkdir -p $(objtree)/tools $(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $* $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $*
# Single targets # Single targets
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
......
...@@ -84,6 +84,15 @@ struct kvm_regs { ...@@ -84,6 +84,15 @@ struct kvm_regs {
#define KVM_VGIC_V2_DIST_SIZE 0x1000 #define KVM_VGIC_V2_DIST_SIZE 0x1000
#define KVM_VGIC_V2_CPU_SIZE 0x2000 #define KVM_VGIC_V2_CPU_SIZE 0x2000
/* Supported VGICv3 address types */
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
#define KVM_VGIC_ITS_ADDR_TYPE 4
#define KVM_VGIC_V3_DIST_SIZE SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */ #define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
......
...@@ -573,6 +573,10 @@ struct kvm_get_htab_header { ...@@ -573,6 +573,10 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba) #define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba)
#define KVM_REG_PPC_DBSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb) #define KVM_REG_PPC_DBSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb)
/* POWER9 registers */
#define KVM_REG_PPC_TIDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
#define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)
/* Transactional Memory checkpointed state: /* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs * This is all GPRs, all VSX regs and a subset of SPRs
*/ */
...@@ -596,6 +600,7 @@ struct kvm_get_htab_header { ...@@ -596,6 +600,7 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67) #define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)
#define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68) #define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)
#define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69) #define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69)
#define KVM_REG_PPC_TM_XER (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a)
/* PPC64 eXternal Interrupt Controller Specification */ /* PPC64 eXternal Interrupt Controller Specification */
#define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */ #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */
......
...@@ -105,6 +105,7 @@ ...@@ -105,6 +105,7 @@
#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ #define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ #define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
...@@ -188,10 +189,14 @@ ...@@ -188,10 +189,14 @@
#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
#define X86_FEATURE_CAT_L3 ( 7*32+ 4) /* Cache Allocation Technology L3 */
#define X86_FEATURE_CAT_L2 ( 7*32+ 5) /* Cache Allocation Technology L2 */
#define X86_FEATURE_CDP_L3 ( 7*32+ 6) /* Code and Data Prioritization L3 */
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
#define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */ #define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */
#define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */ #define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */
...@@ -220,11 +225,13 @@ ...@@ -220,11 +225,13 @@
#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ #define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ #define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ #define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
#define X86_FEATURE_RDT_A ( 9*32+15) /* Resource Director Technology Allocation */
#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ #define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
#define X86_FEATURE_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */ #define X86_FEATURE_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */
#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ #define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ #define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */
#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ #define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
#define X86_FEATURE_AVX512IFMA ( 9*32+21) /* AVX-512 Integer Fused Multiply-Add instructions */
#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ #define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ #define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ #define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
...@@ -278,8 +285,10 @@ ...@@ -278,8 +285,10 @@
#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */ #define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */ #define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
#define X86_FEATURE_RDPID (16*32+ 22) /* RDPID instruction */
/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */ /* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */ #define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
...@@ -310,4 +319,6 @@ ...@@ -310,4 +319,6 @@
#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */ #define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */ #define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */ #define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
#endif /* _ASM_X86_CPUFEATURES_H */ #endif /* _ASM_X86_CPUFEATURES_H */
...@@ -19,6 +19,16 @@ else ...@@ -19,6 +19,16 @@ else
Q=@ Q=@
endif endif
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
quiet=silent_
endif
else # make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
quiet=silent_
endif
endif
build-dir := $(srctree)/tools/build build-dir := $(srctree)/tools/build
# Define $(fixdep) for dep-cmd function # Define $(fixdep) for dep-cmd function
......
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
#define HUGETLBFS_MAGIC 0x958458f6 #define HUGETLBFS_MAGIC 0x958458f6
#endif #endif
#ifndef BPF_FS_MAGIC
#define BPF_FS_MAGIC 0xcafe4a11
#endif
static const char * const sysfs__fs_known_mountpoints[] = { static const char * const sysfs__fs_known_mountpoints[] = {
"/sys", "/sys",
0, 0,
...@@ -75,6 +79,11 @@ static const char * const hugetlbfs__known_mountpoints[] = { ...@@ -75,6 +79,11 @@ static const char * const hugetlbfs__known_mountpoints[] = {
0, 0,
}; };
static const char * const bpf_fs__known_mountpoints[] = {
"/sys/fs/bpf",
0,
};
struct fs { struct fs {
const char *name; const char *name;
const char * const *mounts; const char * const *mounts;
...@@ -89,6 +98,7 @@ enum { ...@@ -89,6 +98,7 @@ enum {
FS__DEBUGFS = 2, FS__DEBUGFS = 2,
FS__TRACEFS = 3, FS__TRACEFS = 3,
FS__HUGETLBFS = 4, FS__HUGETLBFS = 4,
FS__BPF_FS = 5,
}; };
#ifndef TRACEFS_MAGIC #ifndef TRACEFS_MAGIC
...@@ -121,6 +131,11 @@ static struct fs fs__entries[] = { ...@@ -121,6 +131,11 @@ static struct fs fs__entries[] = {
.mounts = hugetlbfs__known_mountpoints, .mounts = hugetlbfs__known_mountpoints,
.magic = HUGETLBFS_MAGIC, .magic = HUGETLBFS_MAGIC,
}, },
[FS__BPF_FS] = {
.name = "bpf",
.mounts = bpf_fs__known_mountpoints,
.magic = BPF_FS_MAGIC,
},
}; };
static bool fs__read_mounts(struct fs *fs) static bool fs__read_mounts(struct fs *fs)
...@@ -280,6 +295,7 @@ FS(procfs, FS__PROCFS); ...@@ -280,6 +295,7 @@ FS(procfs, FS__PROCFS);
FS(debugfs, FS__DEBUGFS); FS(debugfs, FS__DEBUGFS);
FS(tracefs, FS__TRACEFS); FS(tracefs, FS__TRACEFS);
FS(hugetlbfs, FS__HUGETLBFS); FS(hugetlbfs, FS__HUGETLBFS);
FS(bpf_fs, FS__BPF_FS);
int filename__read_int(const char *filename, int *value) int filename__read_int(const char *filename, int *value)
{ {
......
...@@ -22,6 +22,7 @@ FS(procfs) ...@@ -22,6 +22,7 @@ FS(procfs)
FS(debugfs) FS(debugfs)
FS(tracefs) FS(tracefs)
FS(hugetlbfs) FS(hugetlbfs)
FS(bpf_fs)
#undef FS #undef FS
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
* Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
* Copyright (C) 2015 Huawei Inc. * Copyright (C) 2015 Huawei Inc.
* Copyright (C) 2017 Nicira, Inc.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <libgen.h>
#include <inttypes.h> #include <inttypes.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
...@@ -32,6 +34,10 @@ ...@@ -32,6 +34,10 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <libelf.h> #include <libelf.h>
#include <gelf.h> #include <gelf.h>
...@@ -42,6 +48,10 @@ ...@@ -42,6 +48,10 @@
#define EM_BPF 247 #define EM_BPF 247
#endif #endif
#ifndef BPF_FS_MAGIC
#define BPF_FS_MAGIC 0xcafe4a11
#endif
#define __printf(a, b) __attribute__((format(printf, a, b))) #define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2) __printf(1, 2)
...@@ -1237,6 +1247,191 @@ int bpf_object__load(struct bpf_object *obj) ...@@ -1237,6 +1247,191 @@ int bpf_object__load(struct bpf_object *obj)
return err; return err;
} }
static int check_path(const char *path)
{
struct statfs st_fs;
char *dname, *dir;
int err = 0;
if (path == NULL)
return -EINVAL;
dname = strdup(path);
if (dname == NULL)
return -ENOMEM;
dir = dirname(dname);
if (statfs(dir, &st_fs)) {
pr_warning("failed to statfs %s: %s\n", dir, strerror(errno));
err = -errno;
}
free(dname);
if (!err && st_fs.f_type != BPF_FS_MAGIC) {
pr_warning("specified path %s is not on BPF FS\n", path);
err = -EINVAL;
}
return err;
}
int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
int instance)
{
int err;
err = check_path(path);
if (err)
return err;
if (prog == NULL) {
pr_warning("invalid program pointer\n");
return -EINVAL;
}
if (instance < 0 || instance >= prog->instances.nr) {
pr_warning("invalid prog instance %d of prog %s (max %d)\n",
instance, prog->section_name, prog->instances.nr);
return -EINVAL;
}
if (bpf_obj_pin(prog->instances.fds[instance], path)) {
pr_warning("failed to pin program: %s\n", strerror(errno));
return -errno;
}
pr_debug("pinned program '%s'\n", path);
return 0;
}
static int make_dir(const char *path)
{
int err = 0;
if (mkdir(path, 0700) && errno != EEXIST)
err = -errno;
if (err)
pr_warning("failed to mkdir %s: %s\n", path, strerror(-err));
return err;
}
int bpf_program__pin(struct bpf_program *prog, const char *path)
{
int i, err;
err = check_path(path);
if (err)
return err;
if (prog == NULL) {
pr_warning("invalid program pointer\n");
return -EINVAL;
}
if (prog->instances.nr <= 0) {
pr_warning("no instances of prog %s to pin\n",
prog->section_name);
return -EINVAL;
}
err = make_dir(path);
if (err)
return err;
for (i = 0; i < prog->instances.nr; i++) {
char buf[PATH_MAX];
int len;
len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
if (len < 0)
return -EINVAL;
else if (len >= PATH_MAX)
return -ENAMETOOLONG;
err = bpf_program__pin_instance(prog, buf, i);
if (err)
return err;
}
return 0;
}
int bpf_map__pin(struct bpf_map *map, const char *path)
{
int err;
err = check_path(path);
if (err)
return err;
if (map == NULL) {
pr_warning("invalid map pointer\n");
return -EINVAL;
}
if (bpf_obj_pin(map->fd, path)) {
pr_warning("failed to pin map: %s\n", strerror(errno));
return -errno;
}
pr_debug("pinned map '%s'\n", path);
return 0;
}
int bpf_object__pin(struct bpf_object *obj, const char *path)
{
struct bpf_program *prog;
struct bpf_map *map;
int err;
if (!obj)
return -ENOENT;
if (!obj->loaded) {
pr_warning("object not yet loaded; load it first\n");
return -ENOENT;
}
err = make_dir(path);
if (err)
return err;
bpf_map__for_each(map, obj) {
char buf[PATH_MAX];
int len;
len = snprintf(buf, PATH_MAX, "%s/%s", path,
bpf_map__name(map));
if (len < 0)
return -EINVAL;
else if (len >= PATH_MAX)
return -ENAMETOOLONG;
err = bpf_map__pin(map, buf);
if (err)
return err;
}
bpf_object__for_each_program(prog, obj) {
char buf[PATH_MAX];
int len;
len = snprintf(buf, PATH_MAX, "%s/%s", path,
prog->section_name);
if (len < 0)
return -EINVAL;
else if (len >= PATH_MAX)
return -ENAMETOOLONG;
err = bpf_program__pin(prog, buf);
if (err)
return err;
}
return 0;
}
void bpf_object__close(struct bpf_object *obj) void bpf_object__close(struct bpf_object *obj)
{ {
size_t i; size_t i;
......
...@@ -65,6 +65,7 @@ struct bpf_object *bpf_object__open(const char *path); ...@@ -65,6 +65,7 @@ struct bpf_object *bpf_object__open(const char *path);
struct bpf_object *bpf_object__open_buffer(void *obj_buf, struct bpf_object *bpf_object__open_buffer(void *obj_buf,
size_t obj_buf_sz, size_t obj_buf_sz,
const char *name); const char *name);
int bpf_object__pin(struct bpf_object *object, const char *path);
void bpf_object__close(struct bpf_object *object); void bpf_object__close(struct bpf_object *object);
/* Load/unload object into/from kernel */ /* Load/unload object into/from kernel */
...@@ -106,6 +107,9 @@ void *bpf_program__priv(struct bpf_program *prog); ...@@ -106,6 +107,9 @@ void *bpf_program__priv(struct bpf_program *prog);
const char *bpf_program__title(struct bpf_program *prog, bool needs_copy); const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
int bpf_program__fd(struct bpf_program *prog); int bpf_program__fd(struct bpf_program *prog);
int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
int instance);
int bpf_program__pin(struct bpf_program *prog, const char *path);
struct bpf_insn; struct bpf_insn;
...@@ -233,6 +237,7 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); ...@@ -233,6 +237,7 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
int bpf_map__set_priv(struct bpf_map *map, void *priv, int bpf_map__set_priv(struct bpf_map *map, void *priv,
bpf_map_clear_priv_t clear_priv); bpf_map_clear_priv_t clear_priv);
void *bpf_map__priv(struct bpf_map *map); void *bpf_map__priv(struct bpf_map *map);
int bpf_map__pin(struct bpf_map *map, const char *path);
long libbpf_get_error(const void *ptr); long libbpf_get_error(const void *ptr);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "evlist.h" #include "evlist.h"
#include "target.h" #include "target.h"
#include "thread_map.h" #include "thread_map.h"
#include "util/config.h"
#define DEFAULT_TRACER "function_graph" #define DEFAULT_TRACER "function_graph"
...@@ -198,11 +199,31 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) ...@@ -198,11 +199,31 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
return done ? 0 : -1; return done ? 0 : -1;
} }
static int perf_ftrace_config(const char *var, const char *value, void *cb)
{
struct perf_ftrace *ftrace = cb;
if (prefixcmp(var, "ftrace."))
return 0;
if (strcmp(var, "ftrace.tracer"))
return -1;
if (!strcmp(value, "function_graph") ||
!strcmp(value, "function")) {
ftrace->tracer = value;
return 0;
}
pr_err("Please select \"function_graph\" (default) or \"function\"\n");
return -1;
}
int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused)
{ {
int ret; int ret;
struct perf_ftrace ftrace = { struct perf_ftrace ftrace = {
.tracer = "function_graph", .tracer = DEFAULT_TRACER,
.target = { .uid = UINT_MAX, }, .target = { .uid = UINT_MAX, },
}; };
const char * const ftrace_usage[] = { const char * const ftrace_usage[] = {
...@@ -218,6 +239,10 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -218,6 +239,10 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_END() OPT_END()
}; };
ret = perf_config(perf_ftrace_config, &ftrace);
if (ret < 0)
return -1;
argc = parse_options(argc, argv, ftrace_options, ftrace_usage, argc = parse_options(argc, argv, ftrace_options, ftrace_usage,
PARSE_OPT_STOP_AT_NON_OPTION); PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc) if (!argc)
...@@ -231,9 +256,6 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -231,9 +256,6 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused)
if (ret < 0) if (ret < 0)
goto out_delete_evlist; goto out_delete_evlist;
if (ftrace.tracer == NULL)
ftrace.tracer = DEFAULT_TRACER;
ret = __cmd_ftrace(&ftrace, argc, argv); ret = __cmd_ftrace(&ftrace, argc, argv);
out_delete_evlist: out_delete_evlist:
......
...@@ -447,11 +447,13 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -447,11 +447,13 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
NULL NULL
}; };
const char *alias; const char *alias;
int rc = 0; int rc;
load_command_list("perf-", &main_cmds, &other_cmds); load_command_list("perf-", &main_cmds, &other_cmds);
perf_config(perf_help_config, &help_format); rc = perf_config(perf_help_config, &help_format);
if (rc)
return rc;
argc = parse_options_subcommand(argc, argv, builtin_help_options, argc = parse_options_subcommand(argc, argv, builtin_help_options,
builtin_help_subcommands, builtin_help_usage, 0); builtin_help_subcommands, builtin_help_usage, 0);
......
...@@ -1920,10 +1920,12 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1920,10 +1920,12 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
NULL NULL
}; };
struct perf_session *session; struct perf_session *session;
int ret = -1;
const char errmsg[] = "No %s allocation events found. Have you run 'perf kmem record --%s'?\n"; const char errmsg[] = "No %s allocation events found. Have you run 'perf kmem record --%s'?\n";
int ret = perf_config(kmem_config, NULL);
if (ret)
return ret;
perf_config(kmem_config, NULL);
argc = parse_options_subcommand(argc, argv, kmem_options, argc = parse_options_subcommand(argc, argv, kmem_options,
kmem_subcommands, kmem_usage, 0); kmem_subcommands, kmem_usage, 0);
...@@ -1948,6 +1950,8 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1948,6 +1950,8 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
if (session == NULL) if (session == NULL)
return -1; return -1;
ret = -1;
if (kmem_slab) { if (kmem_slab) {
if (!perf_evlist__find_tracepoint_by_name(session->evlist, if (!perf_evlist__find_tracepoint_by_name(session->evlist,
"kmem:kmalloc")) { "kmem:kmalloc")) {
......
...@@ -1670,7 +1670,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1670,7 +1670,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
if (rec->evlist == NULL) if (rec->evlist == NULL)
return -ENOMEM; return -ENOMEM;
perf_config(perf_record_config, rec); err = perf_config(perf_record_config, rec);
if (err)
return err;
argc = parse_options(argc, argv, record_options, record_usage, argc = parse_options(argc, argv, record_options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION); PARSE_OPT_STOP_AT_NON_OPTION);
......
...@@ -847,7 +847,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -847,7 +847,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
if (ret < 0) if (ret < 0)
return ret; return ret;
perf_config(report__config, &report); ret = perf_config(report__config, &report);
if (ret)
return ret;
argc = parse_options(argc, argv, options, report_usage, 0); argc = parse_options(argc, argv, options, report_usage, 0);
if (argc) { if (argc) {
......
...@@ -1216,7 +1216,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1216,7 +1216,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (top.evlist == NULL) if (top.evlist == NULL)
return -ENOMEM; return -ENOMEM;
perf_config(perf_top_config, &top); status = perf_config(perf_top_config, &top);
if (status)
return status;
argc = parse_options(argc, argv, options, top_usage, 0); argc = parse_options(argc, argv, options, top_usage, 0);
if (argc) if (argc)
......
...@@ -90,11 +90,12 @@ static int pager_command_config(const char *var, const char *value, void *data) ...@@ -90,11 +90,12 @@ static int pager_command_config(const char *var, const char *value, void *data)
/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ /* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
int check_pager_config(const char *cmd) int check_pager_config(const char *cmd)
{ {
int err;
struct pager_config c; struct pager_config c;
c.cmd = cmd; c.cmd = cmd;
c.val = -1; c.val = -1;
perf_config(pager_command_config, &c); err = perf_config(pager_command_config, &c);
return c.val; return err ?: c.val;
} }
static int browser_command_config(const char *var, const char *value, void *data) static int browser_command_config(const char *var, const char *value, void *data)
...@@ -113,11 +114,12 @@ static int browser_command_config(const char *var, const char *value, void *data ...@@ -113,11 +114,12 @@ static int browser_command_config(const char *var, const char *value, void *data
*/ */
static int check_browser_config(const char *cmd) static int check_browser_config(const char *cmd)
{ {
int err;
struct pager_config c; struct pager_config c;
c.cmd = cmd; c.cmd = cmd;
c.val = -1; c.val = -1;
perf_config(browser_command_config, &c); err = perf_config(browser_command_config, &c);
return c.val; return err ?: c.val;
} }
static void commit_pager_choice(void) static void commit_pager_choice(void)
...@@ -509,6 +511,7 @@ static void cache_line_size(int *cacheline_sizep) ...@@ -509,6 +511,7 @@ static void cache_line_size(int *cacheline_sizep)
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
int err;
const char *cmd; const char *cmd;
char sbuf[STRERR_BUFSIZE]; char sbuf[STRERR_BUFSIZE];
int value; int value;
...@@ -534,7 +537,9 @@ int main(int argc, const char **argv) ...@@ -534,7 +537,9 @@ int main(int argc, const char **argv)
srandom(time(NULL)); srandom(time(NULL));
perf_config__init(); perf_config__init();
perf_config(perf_default_config, NULL); err = perf_config(perf_default_config, NULL);
if (err)
return err;
set_buildid_dir(NULL); set_buildid_dir(NULL);
/* get debugfs/tracefs mount point from /proc/mounts */ /* get debugfs/tracefs mount point from /proc/mounts */
......
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
#include <util/evlist.h> #include <util/evlist.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <api/fs/fs.h>
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include "tests.h" #include "tests.h"
#include "llvm.h" #include "llvm.h"
#include "debug.h" #include "debug.h"
#define NR_ITERS 111 #define NR_ITERS 111
#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
#ifdef HAVE_LIBBPF_SUPPORT #ifdef HAVE_LIBBPF_SUPPORT
...@@ -54,6 +56,7 @@ static struct { ...@@ -54,6 +56,7 @@ static struct {
const char *msg_load_fail; const char *msg_load_fail;
int (*target_func)(void); int (*target_func)(void);
int expect_result; int expect_result;
bool pin;
} bpf_testcase_table[] = { } bpf_testcase_table[] = {
{ {
LLVM_TESTCASE_BASE, LLVM_TESTCASE_BASE,
...@@ -63,6 +66,17 @@ static struct { ...@@ -63,6 +66,17 @@ static struct {
"load bpf object failed", "load bpf object failed",
&epoll_wait_loop, &epoll_wait_loop,
(NR_ITERS + 1) / 2, (NR_ITERS + 1) / 2,
false,
},
{
LLVM_TESTCASE_BASE,
"BPF pinning",
"[bpf_pinning]",
"fix kbuild first",
"check your vmlinux setting?",
&epoll_wait_loop,
(NR_ITERS + 1) / 2,
true,
}, },
#ifdef HAVE_BPF_PROLOGUE #ifdef HAVE_BPF_PROLOGUE
{ {
...@@ -73,6 +87,7 @@ static struct { ...@@ -73,6 +87,7 @@ static struct {
"check your vmlinux setting?", "check your vmlinux setting?",
&llseek_loop, &llseek_loop,
(NR_ITERS + 1) / 4, (NR_ITERS + 1) / 4,
false,
}, },
#endif #endif
{ {
...@@ -83,6 +98,7 @@ static struct { ...@@ -83,6 +98,7 @@ static struct {
"libbpf error when dealing with relocation", "libbpf error when dealing with relocation",
NULL, NULL,
0, 0,
false,
}, },
}; };
...@@ -226,10 +242,34 @@ static int __test__bpf(int idx) ...@@ -226,10 +242,34 @@ static int __test__bpf(int idx)
goto out; goto out;
} }
if (obj) if (obj) {
ret = do_test(obj, ret = do_test(obj,
bpf_testcase_table[idx].target_func, bpf_testcase_table[idx].target_func,
bpf_testcase_table[idx].expect_result); bpf_testcase_table[idx].expect_result);
if (ret != TEST_OK)
goto out;
if (bpf_testcase_table[idx].pin) {
int err;
if (!bpf_fs__mount()) {
pr_debug("BPF filesystem not mounted\n");
ret = TEST_FAIL;
goto out;
}
err = mkdir(PERF_TEST_BPF_PATH, 0777);
if (err && errno != EEXIST) {
pr_debug("Failed to make perf_test dir: %s\n",
strerror(errno));
ret = TEST_FAIL;
goto out;
}
if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
ret = TEST_FAIL;
if (rm_rf(PERF_TEST_BPF_PATH))
ret = TEST_FAIL;
}
}
out: out:
bpf__clear(); bpf__clear();
return ret; return ret;
......
...@@ -48,6 +48,8 @@ static int parse_callchain_mode(const char *value) ...@@ -48,6 +48,8 @@ static int parse_callchain_mode(const char *value)
callchain_param.mode = CHAIN_FOLDED; callchain_param.mode = CHAIN_FOLDED;
return 0; return 0;
} }
pr_err("Invalid callchain mode: %s\n", value);
return -1; return -1;
} }
...@@ -63,6 +65,8 @@ static int parse_callchain_order(const char *value) ...@@ -63,6 +65,8 @@ static int parse_callchain_order(const char *value)
callchain_param.order_set = true; callchain_param.order_set = true;
return 0; return 0;
} }
pr_err("Invalid callchain order: %s\n", value);
return -1; return -1;
} }
...@@ -80,6 +84,8 @@ static int parse_callchain_sort_key(const char *value) ...@@ -80,6 +84,8 @@ static int parse_callchain_sort_key(const char *value)
callchain_param.branch_callstack = 1; callchain_param.branch_callstack = 1;
return 0; return 0;
} }
pr_err("Invalid callchain sort key: %s\n", value);
return -1; return -1;
} }
...@@ -97,6 +103,8 @@ static int parse_callchain_value(const char *value) ...@@ -97,6 +103,8 @@ static int parse_callchain_value(const char *value)
callchain_param.value = CCVAL_COUNT; callchain_param.value = CCVAL_COUNT;
return 0; return 0;
} }
pr_err("Invalid callchain config key: %s\n", value);
return -1; return -1;
} }
...@@ -210,13 +218,17 @@ int perf_callchain_config(const char *var, const char *value) ...@@ -210,13 +218,17 @@ int perf_callchain_config(const char *var, const char *value)
return parse_callchain_sort_key(value); return parse_callchain_sort_key(value);
if (!strcmp(var, "threshold")) { if (!strcmp(var, "threshold")) {
callchain_param.min_percent = strtod(value, &endptr); callchain_param.min_percent = strtod(value, &endptr);
if (value == endptr) if (value == endptr) {
pr_err("Invalid callchain threshold: %s\n", value);
return -1; return -1;
}
} }
if (!strcmp(var, "print-limit")) { if (!strcmp(var, "print-limit")) {
callchain_param.print_limit = strtod(value, &endptr); callchain_param.print_limit = strtod(value, &endptr);
if (value == endptr) if (value == endptr) {
pr_err("Invalid callchain print limit: %s\n", value);
return -1; return -1;
}
} }
return 0; return 0;
...@@ -437,7 +449,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor) ...@@ -437,7 +449,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
} }
call->ip = cursor_node->ip; call->ip = cursor_node->ip;
call->ms.sym = cursor_node->sym; call->ms.sym = cursor_node->sym;
call->ms.map = cursor_node->map; call->ms.map = map__get(cursor_node->map);
if (cursor_node->branch) { if (cursor_node->branch) {
call->branch_count = 1; call->branch_count = 1;
...@@ -477,6 +489,7 @@ add_child(struct callchain_node *parent, ...@@ -477,6 +489,7 @@ add_child(struct callchain_node *parent,
list_for_each_entry_safe(call, tmp, &new->val, list) { list_for_each_entry_safe(call, tmp, &new->val, list) {
list_del(&call->list); list_del(&call->list);
map__zput(call->ms.map);
free(call); free(call);
} }
free(new); free(new);
...@@ -761,6 +774,7 @@ merge_chain_branch(struct callchain_cursor *cursor, ...@@ -761,6 +774,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
list->ms.map, list->ms.sym, list->ms.map, list->ms.sym,
false, NULL, 0, 0); false, NULL, 0, 0);
list_del(&list->list); list_del(&list->list);
map__zput(list->ms.map);
free(list); free(list);
} }
...@@ -811,7 +825,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor, ...@@ -811,7 +825,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
} }
node->ip = ip; node->ip = ip;
node->map = map; map__zput(node->map);
node->map = map__get(map);
node->sym = sym; node->sym = sym;
node->branch = branch; node->branch = branch;
node->nr_loop_iter = nr_loop_iter; node->nr_loop_iter = nr_loop_iter;
...@@ -1142,11 +1157,13 @@ static void free_callchain_node(struct callchain_node *node) ...@@ -1142,11 +1157,13 @@ static void free_callchain_node(struct callchain_node *node)
list_for_each_entry_safe(list, tmp, &node->parent_val, list) { list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
list_del(&list->list); list_del(&list->list);
map__zput(list->ms.map);
free(list); free(list);
} }
list_for_each_entry_safe(list, tmp, &node->val, list) { list_for_each_entry_safe(list, tmp, &node->val, list) {
list_del(&list->list); list_del(&list->list);
map__zput(list->ms.map);
free(list); free(list);
} }
...@@ -1210,6 +1227,7 @@ int callchain_node__make_parent_list(struct callchain_node *node) ...@@ -1210,6 +1227,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
goto out; goto out;
*new = *chain; *new = *chain;
new->has_children = false; new->has_children = false;
map__get(new->ms.map);
list_add_tail(&new->list, &head); list_add_tail(&new->list, &head);
} }
parent = parent->parent; parent = parent->parent;
...@@ -1230,6 +1248,7 @@ int callchain_node__make_parent_list(struct callchain_node *node) ...@@ -1230,6 +1248,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
out: out:
list_for_each_entry_safe(chain, new, &head, list) { list_for_each_entry_safe(chain, new, &head, list) {
list_del(&chain->list); list_del(&chain->list);
map__zput(chain->ms.map);
free(chain); free(chain);
} }
return -ENOMEM; return -ENOMEM;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include "event.h" #include "event.h"
#include "map.h"
#include "symbol.h" #include "symbol.h"
#define HELP_PAD "\t\t\t\t" #define HELP_PAD "\t\t\t\t"
...@@ -184,8 +185,13 @@ int callchain_merge(struct callchain_cursor *cursor, ...@@ -184,8 +185,13 @@ int callchain_merge(struct callchain_cursor *cursor,
*/ */
static inline void callchain_cursor_reset(struct callchain_cursor *cursor) static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
{ {
struct callchain_cursor_node *node;
cursor->nr = 0; cursor->nr = 0;
cursor->last = &cursor->first; cursor->last = &cursor->first;
for (node = cursor->first; node != NULL; node = node->next)
map__zput(node->map);
} }
int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
......
...@@ -386,8 +386,10 @@ static int perf_buildid_config(const char *var, const char *value) ...@@ -386,8 +386,10 @@ static int perf_buildid_config(const char *var, const char *value)
if (!strcmp(var, "buildid.dir")) { if (!strcmp(var, "buildid.dir")) {
const char *dir = perf_config_dirname(var, value); const char *dir = perf_config_dirname(var, value);
if (!dir) if (!dir) {
pr_err("Invalid buildid directory!\n");
return -1; return -1;
}
strncpy(buildid_dir, dir, MAXPATHLEN-1); strncpy(buildid_dir, dir, MAXPATHLEN-1);
buildid_dir[MAXPATHLEN-1] = '\0'; buildid_dir[MAXPATHLEN-1] = '\0';
} }
...@@ -405,10 +407,9 @@ static int perf_default_core_config(const char *var __maybe_unused, ...@@ -405,10 +407,9 @@ static int perf_default_core_config(const char *var __maybe_unused,
static int perf_ui_config(const char *var, const char *value) static int perf_ui_config(const char *var, const char *value)
{ {
/* Add other config variables here. */ /* Add other config variables here. */
if (!strcmp(var, "ui.show-headers")) { if (!strcmp(var, "ui.show-headers"))
symbol_conf.show_hist_headers = perf_config_bool(var, value); symbol_conf.show_hist_headers = perf_config_bool(var, value);
return 0;
}
return 0; return 0;
} }
...@@ -646,8 +647,13 @@ static int perf_config_set__init(struct perf_config_set *set) ...@@ -646,8 +647,13 @@ static int perf_config_set__init(struct perf_config_set *set)
goto out; goto out;
} }
if (stat(user_config, &st) < 0) if (stat(user_config, &st) < 0) {
if (errno == ENOENT)
ret = 0;
goto out_free; goto out_free;
}
ret = 0;
if (st.st_uid && (st.st_uid != geteuid())) { if (st.st_uid && (st.st_uid != geteuid())) {
warning("File %s not owned by current user or root, " warning("File %s not owned by current user or root, "
...@@ -655,11 +661,8 @@ static int perf_config_set__init(struct perf_config_set *set) ...@@ -655,11 +661,8 @@ static int perf_config_set__init(struct perf_config_set *set)
goto out_free; goto out_free;
} }
if (!st.st_size) if (st.st_size)
goto out_free; ret = perf_config_from_file(collect_config, user_config, set);
ret = perf_config_from_file(collect_config, user_config, set);
out_free: out_free:
free(user_config); free(user_config);
} }
......
...@@ -1473,7 +1473,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, ...@@ -1473,7 +1473,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,
}, },
}; };
struct ctf_writer *cw = &c.writer; struct ctf_writer *cw = &c.writer;
int err = -1; int err;
if (opts->all) { if (opts->all) {
c.tool.comm = process_comm_event; c.tool.comm = process_comm_event;
...@@ -1481,12 +1481,15 @@ int bt_convert__perf2ctf(const char *input, const char *path, ...@@ -1481,12 +1481,15 @@ int bt_convert__perf2ctf(const char *input, const char *path,
c.tool.fork = process_fork_event; c.tool.fork = process_fork_event;
} }
perf_config(convert__config, &c); err = perf_config(convert__config, &c);
if (err)
return err;
/* CTF writer */ /* CTF writer */
if (ctf_writer__init(cw, path)) if (ctf_writer__init(cw, path))
return -1; return -1;
err = -1;
/* perf.data session */ /* perf.data session */
session = perf_session__new(&file, 0, &c.tool); session = perf_session__new(&file, 0, &c.tool);
if (!session) if (!session)
......
#include "util.h" #include "util.h"
#include "build-id.h" #include "build-id.h"
#include "hist.h" #include "hist.h"
#include "map.h"
#include "session.h" #include "session.h"
#include "sort.h" #include "sort.h"
#include "evlist.h" #include "evlist.h"
...@@ -1019,6 +1020,10 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, ...@@ -1019,6 +1020,10 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
int max_stack_depth, void *arg) int max_stack_depth, void *arg)
{ {
int err, err2; int err, err2;
struct map *alm = NULL;
if (al && al->map)
alm = map__get(al->map);
err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent, err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
iter->evsel, al, max_stack_depth); iter->evsel, al, max_stack_depth);
...@@ -1058,6 +1063,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, ...@@ -1058,6 +1063,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
if (!err) if (!err)
err = err2; err = err2;
map__put(alm);
return err; return err;
} }
...@@ -2439,8 +2446,10 @@ int parse_filter_percentage(const struct option *opt __maybe_unused, ...@@ -2439,8 +2446,10 @@ int parse_filter_percentage(const struct option *opt __maybe_unused,
symbol_conf.filter_relative = true; symbol_conf.filter_relative = true;
else if (!strcmp(arg, "absolute")) else if (!strcmp(arg, "absolute"))
symbol_conf.filter_relative = false; symbol_conf.filter_relative = false;
else else {
pr_debug("Invalud percentage: %s\n", arg);
return -1; return -1;
}
return 0; return 0;
} }
......
...@@ -2159,7 +2159,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event, ...@@ -2159,7 +2159,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
addr_filters__init(&pt->filts); addr_filters__init(&pt->filts);
perf_config(intel_pt_perf_config, pt); err = perf_config(intel_pt_perf_config, pt);
if (err)
goto err_free;
err = auxtrace_queues__init(&pt->queues); err = auxtrace_queues__init(&pt->queues);
if (err) if (err)
......
...@@ -48,8 +48,10 @@ int perf_llvm_config(const char *var, const char *value) ...@@ -48,8 +48,10 @@ int perf_llvm_config(const char *var, const char *value)
llvm_param.kbuild_opts = strdup(value); llvm_param.kbuild_opts = strdup(value);
else if (!strcmp(var, "dump-obj")) else if (!strcmp(var, "dump-obj"))
llvm_param.dump_obj = !!perf_config_bool(var, value); llvm_param.dump_obj = !!perf_config_bool(var, value);
else else {
pr_debug("Invalid LLVM config option: %s\n", value);
return -1; return -1;
}
llvm_param.user_set_param = true; llvm_param.user_set_param = true;
return 0; return 0;
} }
......
...@@ -170,6 +170,12 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) ...@@ -170,6 +170,12 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
return false; return false;
} }
#define for_each_event(dir, dent, tps) \
while ((dent = readdir(dir))) \
if (dent->d_type == DT_DIR && \
(strcmp(dent->d_name, ".")) && \
(strcmp(dent->d_name, ".."))) \
static int copy_event_system(const char *sys, struct tracepoint_path *tps) static int copy_event_system(const char *sys, struct tracepoint_path *tps)
{ {
struct dirent *dent; struct dirent *dent;
...@@ -186,12 +192,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps) ...@@ -186,12 +192,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
return -errno; return -errno;
} }
while ((dent = readdir(dir))) { for_each_event(dir, dent, tps) {
if (dent->d_type != DT_DIR || if (!name_in_tp_list(dent->d_name, tps))
strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0 ||
!name_in_tp_list(dent->d_name, tps))
continue; continue;
if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) { if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
...@@ -210,12 +214,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps) ...@@ -210,12 +214,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
} }
rewinddir(dir); rewinddir(dir);
while ((dent = readdir(dir))) { for_each_event(dir, dent, tps) {
if (dent->d_type != DT_DIR || if (!name_in_tp_list(dent->d_name, tps))
strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0 ||
!name_in_tp_list(dent->d_name, tps))
continue; continue;
if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) { if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
...@@ -290,13 +292,11 @@ static int record_event_files(struct tracepoint_path *tps) ...@@ -290,13 +292,11 @@ static int record_event_files(struct tracepoint_path *tps)
goto out; goto out;
} }
while ((dent = readdir(dir))) { for_each_event(dir, dent, tps) {
if (dent->d_type != DT_DIR || if (strcmp(dent->d_name, "ftrace") == 0 ||
strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0 ||
strcmp(dent->d_name, "ftrace") == 0 ||
!system_in_tp_list(dent->d_name, tps)) !system_in_tp_list(dent->d_name, tps))
continue; continue;
count++; count++;
} }
...@@ -307,13 +307,11 @@ static int record_event_files(struct tracepoint_path *tps) ...@@ -307,13 +307,11 @@ static int record_event_files(struct tracepoint_path *tps)
} }
rewinddir(dir); rewinddir(dir);
while ((dent = readdir(dir))) { for_each_event(dir, dent, tps) {
if (dent->d_type != DT_DIR || if (strcmp(dent->d_name, "ftrace") == 0 ||
strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0 ||
strcmp(dent->d_name, "ftrace") == 0 ||
!system_in_tp_list(dent->d_name, tps)) !system_in_tp_list(dent->d_name, tps))
continue; continue;
if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) { if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
......
...@@ -85,7 +85,7 @@ int mkdir_p(char *path, mode_t mode) ...@@ -85,7 +85,7 @@ int mkdir_p(char *path, mode_t mode)
return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
} }
int rm_rf(char *path) int rm_rf(const char *path)
{ {
DIR *dir; DIR *dir;
int ret = 0; int ret = 0;
......
...@@ -209,7 +209,7 @@ static inline int sane_case(int x, int high) ...@@ -209,7 +209,7 @@ static inline int sane_case(int x, int high)
} }
int mkdir_p(char *path, mode_t mode); int mkdir_p(char *path, mode_t mode);
int rm_rf(char *path); int rm_rf(const char *path);
struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *)); struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *));
bool lsdir_no_dot_filter(const char *name, struct dirent *d); bool lsdir_no_dot_filter(const char *name, struct dirent *d);
int copyfile(const char *from, const char *to); int copyfile(const char *from, const char *to);
......
...@@ -46,6 +46,16 @@ else ...@@ -46,6 +46,16 @@ else
NO_SUBDIR = : NO_SUBDIR = :
endif endif
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
silent=1
endif
else # make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
silent=1
endif
endif
# #
# Define a callable command for descending to a new directory # Define a callable command for descending to a new directory
# #
...@@ -58,7 +68,7 @@ descend = \ ...@@ -58,7 +68,7 @@ descend = \
QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
QUIET_SUBDIR1 = QUIET_SUBDIR1 =
ifneq ($(findstring $(MAKEFLAGS),s),s) ifneq ($(silent),1)
ifneq ($(V),1) ifneq ($(V),1)
QUIET_CC = @echo ' CC '$@; QUIET_CC = @echo ' CC '$@;
QUIET_CC_FPIC = @echo ' CC FPIC '$@; QUIET_CC_FPIC = @echo ' CC FPIC '$@;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment