mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
perf/core improvements and fixes:
New features: . Allow configuring a 'perf ftrace' default --tracer (Taeung Song) Infrastructure: . 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: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJYkcuWAAoJENZQFvNTUqpAMDgQALp5+x7KkWikCBWe4t3CX0Rq +VQcanFJ9eqRYsoBBJ7F4A+E+9AKMjzYTfoPyFv1S+W9cCFsEKeOuVsICtM8PpjB UEUgQGJjAfRK/IcDeeQSzGqWMbiVgPv2fE5W/zPV2V+i25uBVHbZkOmPB7xcCUsY /ORA5RT93uaHkAv9je8/bGPrQp5y6aDlKh6W3ePD4UwBnFmy8QMOx+24uc4t/uZM G2cjTcz5HEXlUE0wGCO4C2T2mcEchGDVtBM1Uz0pKmE3eMB3ZluA5+XpHvmLQTQ5 dZQhm3mLnllNz4Zbg2yUkIq3HEaARav1db1rUC0P1ySvYventvGRd181dpugyWdu 3XuPPqb4QjHT7x4eYcXJY4HuwrLChbVKn3lFo8Mhfd6HpMxQHFspTwyIVxLYoq8I LcZE3waOYYki5yaRTQiHtWypvn6RNBOLvfvU6DoINENHMJ82DgsqgXoIA8bp++YX miO5NHYheWBi4DmBqh9oSKvq5hriKDS5M2QTyZEkzItzOE2lsq0tl2neLg4SQCNC ajM3szUYje/cvSoB5K3r28C9vWwTLXvnOE0B6TpDbh3y7xqdNX59oDSNu4dnWwwv fN8O7cJo2X5W/JjScCuMSBg+V+UgIl2JfKCxfd0AdXL/e1UsTz9dV6CtgMGtN664 YCxiQKnJeZLViXZfVmaM =OCSZ -----END PGP SIGNATURE----- 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: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
d7cb3a507d
6
Makefile
6
Makefile
@ -87,10 +87,12 @@ endif
|
||||
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
|
||||
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
|
||||
quiet=silent_
|
||||
tools_silent=s
|
||||
endif
|
||||
else # make-3.8x
|
||||
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
|
||||
quiet=silent_
|
||||
tools_silent=-s
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1607,11 +1609,11 @@ image_name:
|
||||
# Clear a bunch of variables before executing the submake
|
||||
tools/: FORCE
|
||||
$(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
|
||||
$(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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@ -84,6 +84,15 @@ struct kvm_regs {
|
||||
#define KVM_VGIC_V2_DIST_SIZE 0x1000
|
||||
#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_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
|
||||
|
||||
|
@ -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_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:
|
||||
* This is all GPRs, all VSX regs and a subset of SPRs
|
||||
*/
|
||||
@ -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_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_XER (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a)
|
||||
|
||||
/* PPC64 eXternal Interrupt Controller Specification */
|
||||
#define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */
|
||||
|
@ -105,6 +105,7 @@
|
||||
#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
|
||||
#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_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
||||
#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
|
||||
@ -188,10 +189,14 @@
|
||||
|
||||
#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_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_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_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */
|
||||
#define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */
|
||||
@ -220,11 +225,13 @@
|
||||
#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
|
||||
#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
|
||||
#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_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */
|
||||
#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_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_CLWB ( 9*32+24) /* CLWB instruction */
|
||||
#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
|
||||
@ -278,8 +285,10 @@
|
||||
#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
|
||||
|
||||
/* 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_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 */
|
||||
#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
|
||||
@ -310,4 +319,6 @@
|
||||
#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_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 */
|
||||
|
@ -19,6 +19,16 @@ else
|
||||
Q=@
|
||||
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
|
||||
|
||||
# Define $(fixdep) for dep-cmd function
|
||||
|
@ -38,6 +38,10 @@
|
||||
#define HUGETLBFS_MAGIC 0x958458f6
|
||||
#endif
|
||||
|
||||
#ifndef BPF_FS_MAGIC
|
||||
#define BPF_FS_MAGIC 0xcafe4a11
|
||||
#endif
|
||||
|
||||
static const char * const sysfs__fs_known_mountpoints[] = {
|
||||
"/sys",
|
||||
0,
|
||||
@ -75,6 +79,11 @@ static const char * const hugetlbfs__known_mountpoints[] = {
|
||||
0,
|
||||
};
|
||||
|
||||
static const char * const bpf_fs__known_mountpoints[] = {
|
||||
"/sys/fs/bpf",
|
||||
0,
|
||||
};
|
||||
|
||||
struct fs {
|
||||
const char *name;
|
||||
const char * const *mounts;
|
||||
@ -89,6 +98,7 @@ enum {
|
||||
FS__DEBUGFS = 2,
|
||||
FS__TRACEFS = 3,
|
||||
FS__HUGETLBFS = 4,
|
||||
FS__BPF_FS = 5,
|
||||
};
|
||||
|
||||
#ifndef TRACEFS_MAGIC
|
||||
@ -121,6 +131,11 @@ static struct fs fs__entries[] = {
|
||||
.mounts = hugetlbfs__known_mountpoints,
|
||||
.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)
|
||||
@ -280,6 +295,7 @@ FS(procfs, FS__PROCFS);
|
||||
FS(debugfs, FS__DEBUGFS);
|
||||
FS(tracefs, FS__TRACEFS);
|
||||
FS(hugetlbfs, FS__HUGETLBFS);
|
||||
FS(bpf_fs, FS__BPF_FS);
|
||||
|
||||
int filename__read_int(const char *filename, int *value)
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ FS(procfs)
|
||||
FS(debugfs)
|
||||
FS(tracefs)
|
||||
FS(hugetlbfs)
|
||||
FS(bpf_fs)
|
||||
|
||||
#undef FS
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
|
||||
* Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
|
||||
* Copyright (C) 2015 Huawei Inc.
|
||||
* Copyright (C) 2017 Nicira, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -22,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <libgen.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -32,6 +34,10 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bpf.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 <gelf.h>
|
||||
|
||||
@ -42,6 +48,10 @@
|
||||
#define EM_BPF 247
|
||||
#endif
|
||||
|
||||
#ifndef BPF_FS_MAGIC
|
||||
#define BPF_FS_MAGIC 0xcafe4a11
|
||||
#endif
|
||||
|
||||
#define __printf(a, b) __attribute__((format(printf, a, b)))
|
||||
|
||||
__printf(1, 2)
|
||||
@ -1237,6 +1247,191 @@ out:
|
||||
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)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -65,6 +65,7 @@ struct bpf_object *bpf_object__open(const char *path);
|
||||
struct bpf_object *bpf_object__open_buffer(void *obj_buf,
|
||||
size_t obj_buf_sz,
|
||||
const char *name);
|
||||
int bpf_object__pin(struct bpf_object *object, const char *path);
|
||||
void bpf_object__close(struct bpf_object *object);
|
||||
|
||||
/* Load/unload object into/from kernel */
|
||||
@ -106,6 +107,9 @@ void *bpf_program__priv(struct bpf_program *prog);
|
||||
const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
|
||||
|
||||
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;
|
||||
|
||||
@ -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,
|
||||
bpf_map_clear_priv_t clear_priv);
|
||||
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);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "evlist.h"
|
||||
#include "target.h"
|
||||
#include "thread_map.h"
|
||||
#include "util/config.h"
|
||||
|
||||
|
||||
#define DEFAULT_TRACER "function_graph"
|
||||
@ -198,11 +199,31 @@ out:
|
||||
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 ret;
|
||||
struct perf_ftrace ftrace = {
|
||||
.tracer = "function_graph",
|
||||
.tracer = DEFAULT_TRACER,
|
||||
.target = { .uid = UINT_MAX, },
|
||||
};
|
||||
const char * const ftrace_usage[] = {
|
||||
@ -218,6 +239,10 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
ret = perf_config(perf_ftrace_config, &ftrace);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
argc = parse_options(argc, argv, ftrace_options, ftrace_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
if (!argc)
|
||||
@ -231,9 +256,6 @@ int cmd_ftrace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (ret < 0)
|
||||
goto out_delete_evlist;
|
||||
|
||||
if (ftrace.tracer == NULL)
|
||||
ftrace.tracer = DEFAULT_TRACER;
|
||||
|
||||
ret = __cmd_ftrace(&ftrace, argc, argv);
|
||||
|
||||
out_delete_evlist:
|
||||
|
@ -447,11 +447,13 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
NULL
|
||||
};
|
||||
const char *alias;
|
||||
int rc = 0;
|
||||
int rc;
|
||||
|
||||
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,
|
||||
builtin_help_subcommands, builtin_help_usage, 0);
|
||||
|
@ -1920,10 +1920,12 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
NULL
|
||||
};
|
||||
struct perf_session *session;
|
||||
int ret = -1;
|
||||
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,
|
||||
kmem_subcommands, kmem_usage, 0);
|
||||
|
||||
@ -1948,6 +1950,8 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
|
||||
ret = -1;
|
||||
|
||||
if (kmem_slab) {
|
||||
if (!perf_evlist__find_tracepoint_by_name(session->evlist,
|
||||
"kmem:kmalloc")) {
|
||||
|
@ -1670,7 +1670,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (rec->evlist == NULL)
|
||||
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,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
@ -847,7 +847,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (ret < 0)
|
||||
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);
|
||||
if (argc) {
|
||||
|
@ -1216,7 +1216,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (top.evlist == NULL)
|
||||
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);
|
||||
if (argc)
|
||||
|
@ -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" */
|
||||
int check_pager_config(const char *cmd)
|
||||
{
|
||||
int err;
|
||||
struct pager_config c;
|
||||
c.cmd = cmd;
|
||||
c.val = -1;
|
||||
perf_config(pager_command_config, &c);
|
||||
return c.val;
|
||||
err = perf_config(pager_command_config, &c);
|
||||
return err ?: c.val;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int err;
|
||||
struct pager_config c;
|
||||
c.cmd = cmd;
|
||||
c.val = -1;
|
||||
perf_config(browser_command_config, &c);
|
||||
return c.val;
|
||||
err = perf_config(browser_command_config, &c);
|
||||
return err ?: c.val;
|
||||
}
|
||||
|
||||
static void commit_pager_choice(void)
|
||||
@ -509,6 +511,7 @@ static void cache_line_size(int *cacheline_sizep)
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
int err;
|
||||
const char *cmd;
|
||||
char sbuf[STRERR_BUFSIZE];
|
||||
int value;
|
||||
@ -534,7 +537,9 @@ int main(int argc, const char **argv)
|
||||
srandom(time(NULL));
|
||||
|
||||
perf_config__init();
|
||||
perf_config(perf_default_config, NULL);
|
||||
err = perf_config(perf_default_config, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
set_buildid_dir(NULL);
|
||||
|
||||
/* get debugfs/tracefs mount point from /proc/mounts */
|
||||
|
@ -5,11 +5,13 @@
|
||||
#include <util/evlist.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/filter.h>
|
||||
#include <api/fs/fs.h>
|
||||
#include <bpf/bpf.h>
|
||||
#include "tests.h"
|
||||
#include "llvm.h"
|
||||
#include "debug.h"
|
||||
#define NR_ITERS 111
|
||||
#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
|
||||
|
||||
#ifdef HAVE_LIBBPF_SUPPORT
|
||||
|
||||
@ -54,6 +56,7 @@ static struct {
|
||||
const char *msg_load_fail;
|
||||
int (*target_func)(void);
|
||||
int expect_result;
|
||||
bool pin;
|
||||
} bpf_testcase_table[] = {
|
||||
{
|
||||
LLVM_TESTCASE_BASE,
|
||||
@ -63,6 +66,17 @@ static struct {
|
||||
"load bpf object failed",
|
||||
&epoll_wait_loop,
|
||||
(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
|
||||
{
|
||||
@ -73,6 +87,7 @@ static struct {
|
||||
"check your vmlinux setting?",
|
||||
&llseek_loop,
|
||||
(NR_ITERS + 1) / 4,
|
||||
false,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
@ -83,6 +98,7 @@ static struct {
|
||||
"libbpf error when dealing with relocation",
|
||||
NULL,
|
||||
0,
|
||||
false,
|
||||
},
|
||||
};
|
||||
|
||||
@ -226,10 +242,34 @@ static int __test__bpf(int idx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (obj)
|
||||
if (obj) {
|
||||
ret = do_test(obj,
|
||||
bpf_testcase_table[idx].target_func,
|
||||
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:
|
||||
bpf__clear();
|
||||
return ret;
|
||||
|
@ -48,6 +48,8 @@ static int parse_callchain_mode(const char *value)
|
||||
callchain_param.mode = CHAIN_FOLDED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_err("Invalid callchain mode: %s\n", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -63,6 +65,8 @@ static int parse_callchain_order(const char *value)
|
||||
callchain_param.order_set = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_err("Invalid callchain order: %s\n", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -80,6 +84,8 @@ static int parse_callchain_sort_key(const char *value)
|
||||
callchain_param.branch_callstack = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_err("Invalid callchain sort key: %s\n", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -97,6 +103,8 @@ static int parse_callchain_value(const char *value)
|
||||
callchain_param.value = CCVAL_COUNT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_err("Invalid callchain config key: %s\n", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -210,13 +218,17 @@ int perf_callchain_config(const char *var, const char *value)
|
||||
return parse_callchain_sort_key(value);
|
||||
if (!strcmp(var, "threshold")) {
|
||||
callchain_param.min_percent = strtod(value, &endptr);
|
||||
if (value == endptr)
|
||||
if (value == endptr) {
|
||||
pr_err("Invalid callchain threshold: %s\n", value);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!strcmp(var, "print-limit")) {
|
||||
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 0;
|
||||
@ -437,7 +449,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
|
||||
}
|
||||
call->ip = cursor_node->ip;
|
||||
call->ms.sym = cursor_node->sym;
|
||||
call->ms.map = cursor_node->map;
|
||||
call->ms.map = map__get(cursor_node->map);
|
||||
|
||||
if (cursor_node->branch) {
|
||||
call->branch_count = 1;
|
||||
@ -477,6 +489,7 @@ add_child(struct callchain_node *parent,
|
||||
|
||||
list_for_each_entry_safe(call, tmp, &new->val, list) {
|
||||
list_del(&call->list);
|
||||
map__zput(call->ms.map);
|
||||
free(call);
|
||||
}
|
||||
free(new);
|
||||
@ -761,6 +774,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
|
||||
list->ms.map, list->ms.sym,
|
||||
false, NULL, 0, 0);
|
||||
list_del(&list->list);
|
||||
map__zput(list->ms.map);
|
||||
free(list);
|
||||
}
|
||||
|
||||
@ -811,7 +825,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
|
||||
}
|
||||
|
||||
node->ip = ip;
|
||||
node->map = map;
|
||||
map__zput(node->map);
|
||||
node->map = map__get(map);
|
||||
node->sym = sym;
|
||||
node->branch = branch;
|
||||
node->nr_loop_iter = nr_loop_iter;
|
||||
@ -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_del(&list->list);
|
||||
map__zput(list->ms.map);
|
||||
free(list);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(list, tmp, &node->val, list) {
|
||||
list_del(&list->list);
|
||||
map__zput(list->ms.map);
|
||||
free(list);
|
||||
}
|
||||
|
||||
@ -1210,6 +1227,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
|
||||
goto out;
|
||||
*new = *chain;
|
||||
new->has_children = false;
|
||||
map__get(new->ms.map);
|
||||
list_add_tail(&new->list, &head);
|
||||
}
|
||||
parent = parent->parent;
|
||||
@ -1230,6 +1248,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
|
||||
out:
|
||||
list_for_each_entry_safe(chain, new, &head, list) {
|
||||
list_del(&chain->list);
|
||||
map__zput(chain->ms.map);
|
||||
free(chain);
|
||||
}
|
||||
return -ENOMEM;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include "event.h"
|
||||
#include "map.h"
|
||||
#include "symbol.h"
|
||||
|
||||
#define HELP_PAD "\t\t\t\t"
|
||||
@ -184,8 +185,13 @@ int callchain_merge(struct callchain_cursor *cursor,
|
||||
*/
|
||||
static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
|
||||
{
|
||||
struct callchain_cursor_node *node;
|
||||
|
||||
cursor->nr = 0;
|
||||
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,
|
||||
|
@ -386,8 +386,10 @@ static int perf_buildid_config(const char *var, const char *value)
|
||||
if (!strcmp(var, "buildid.dir")) {
|
||||
const char *dir = perf_config_dirname(var, value);
|
||||
|
||||
if (!dir)
|
||||
if (!dir) {
|
||||
pr_err("Invalid buildid directory!\n");
|
||||
return -1;
|
||||
}
|
||||
strncpy(buildid_dir, dir, MAXPATHLEN-1);
|
||||
buildid_dir[MAXPATHLEN-1] = '\0';
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
/* 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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -646,8 +647,13 @@ static int perf_config_set__init(struct perf_config_set *set)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (stat(user_config, &st) < 0)
|
||||
if (stat(user_config, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
ret = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
if (st.st_uid && (st.st_uid != geteuid())) {
|
||||
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)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!st.st_size)
|
||||
goto out_free;
|
||||
|
||||
ret = perf_config_from_file(collect_config, user_config, set);
|
||||
|
||||
if (st.st_size)
|
||||
ret = perf_config_from_file(collect_config, user_config, set);
|
||||
out_free:
|
||||
free(user_config);
|
||||
}
|
||||
|
@ -1473,7 +1473,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,
|
||||
},
|
||||
};
|
||||
struct ctf_writer *cw = &c.writer;
|
||||
int err = -1;
|
||||
int err;
|
||||
|
||||
if (opts->all) {
|
||||
c.tool.comm = process_comm_event;
|
||||
@ -1481,12 +1481,15 @@ int bt_convert__perf2ctf(const char *input, const char *path,
|
||||
c.tool.fork = process_fork_event;
|
||||
}
|
||||
|
||||
perf_config(convert__config, &c);
|
||||
err = perf_config(convert__config, &c);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* CTF writer */
|
||||
if (ctf_writer__init(cw, path))
|
||||
return -1;
|
||||
|
||||
err = -1;
|
||||
/* perf.data session */
|
||||
session = perf_session__new(&file, 0, &c.tool);
|
||||
if (!session)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "util.h"
|
||||
#include "build-id.h"
|
||||
#include "hist.h"
|
||||
#include "map.h"
|
||||
#include "session.h"
|
||||
#include "sort.h"
|
||||
#include "evlist.h"
|
||||
@ -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 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,
|
||||
iter->evsel, al, max_stack_depth);
|
||||
@ -1058,6 +1063,8 @@ out:
|
||||
if (!err)
|
||||
err = err2;
|
||||
|
||||
map__put(alm);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -2439,8 +2446,10 @@ int parse_filter_percentage(const struct option *opt __maybe_unused,
|
||||
symbol_conf.filter_relative = true;
|
||||
else if (!strcmp(arg, "absolute"))
|
||||
symbol_conf.filter_relative = false;
|
||||
else
|
||||
else {
|
||||
pr_debug("Invalud percentage: %s\n", arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2159,7 +2159,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
|
||||
|
||||
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);
|
||||
if (err)
|
||||
|
@ -48,8 +48,10 @@ int perf_llvm_config(const char *var, const char *value)
|
||||
llvm_param.kbuild_opts = strdup(value);
|
||||
else if (!strcmp(var, "dump-obj"))
|
||||
llvm_param.dump_obj = !!perf_config_bool(var, value);
|
||||
else
|
||||
else {
|
||||
pr_debug("Invalid LLVM config option: %s\n", value);
|
||||
return -1;
|
||||
}
|
||||
llvm_param.user_set_param = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -170,6 +170,12 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
|
||||
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)
|
||||
{
|
||||
struct dirent *dent;
|
||||
@ -186,12 +192,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
while ((dent = readdir(dir))) {
|
||||
if (dent->d_type != DT_DIR ||
|
||||
strcmp(dent->d_name, ".") == 0 ||
|
||||
strcmp(dent->d_name, "..") == 0 ||
|
||||
!name_in_tp_list(dent->d_name, tps))
|
||||
for_each_event(dir, dent, tps) {
|
||||
if (!name_in_tp_list(dent->d_name, tps))
|
||||
continue;
|
||||
|
||||
if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
@ -210,12 +214,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
|
||||
}
|
||||
|
||||
rewinddir(dir);
|
||||
while ((dent = readdir(dir))) {
|
||||
if (dent->d_type != DT_DIR ||
|
||||
strcmp(dent->d_name, ".") == 0 ||
|
||||
strcmp(dent->d_name, "..") == 0 ||
|
||||
!name_in_tp_list(dent->d_name, tps))
|
||||
for_each_event(dir, dent, tps) {
|
||||
if (!name_in_tp_list(dent->d_name, tps))
|
||||
continue;
|
||||
|
||||
if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
@ -290,13 +292,11 @@ static int record_event_files(struct tracepoint_path *tps)
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((dent = readdir(dir))) {
|
||||
if (dent->d_type != DT_DIR ||
|
||||
strcmp(dent->d_name, ".") == 0 ||
|
||||
strcmp(dent->d_name, "..") == 0 ||
|
||||
strcmp(dent->d_name, "ftrace") == 0 ||
|
||||
for_each_event(dir, dent, tps) {
|
||||
if (strcmp(dent->d_name, "ftrace") == 0 ||
|
||||
!system_in_tp_list(dent->d_name, tps))
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
@ -307,13 +307,11 @@ static int record_event_files(struct tracepoint_path *tps)
|
||||
}
|
||||
|
||||
rewinddir(dir);
|
||||
while ((dent = readdir(dir))) {
|
||||
if (dent->d_type != DT_DIR ||
|
||||
strcmp(dent->d_name, ".") == 0 ||
|
||||
strcmp(dent->d_name, "..") == 0 ||
|
||||
strcmp(dent->d_name, "ftrace") == 0 ||
|
||||
for_each_event(dir, dent, tps) {
|
||||
if (strcmp(dent->d_name, "ftrace") == 0 ||
|
||||
!system_in_tp_list(dent->d_name, tps))
|
||||
continue;
|
||||
|
||||
if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
|
@ -85,7 +85,7 @@ int mkdir_p(char *path, mode_t mode)
|
||||
return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
|
||||
}
|
||||
|
||||
int rm_rf(char *path)
|
||||
int rm_rf(const char *path)
|
||||
{
|
||||
DIR *dir;
|
||||
int ret = 0;
|
||||
|
@ -209,7 +209,7 @@ static inline int sane_case(int x, int high)
|
||||
}
|
||||
|
||||
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 *));
|
||||
bool lsdir_no_dot_filter(const char *name, struct dirent *d);
|
||||
int copyfile(const char *from, const char *to);
|
||||
|
@ -46,6 +46,16 @@ else
|
||||
NO_SUBDIR = :
|
||||
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
|
||||
#
|
||||
@ -58,7 +68,7 @@ descend = \
|
||||
QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
|
||||
QUIET_SUBDIR1 =
|
||||
|
||||
ifneq ($(findstring $(MAKEFLAGS),s),s)
|
||||
ifneq ($(silent),1)
|
||||
ifneq ($(V),1)
|
||||
QUIET_CC = @echo ' CC '$@;
|
||||
QUIET_CC_FPIC = @echo ' CC FPIC '$@;
|
||||
|
Loading…
Reference in New Issue
Block a user