Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo-20160713' of git://git.kernel.org/pub/…
Browse files Browse the repository at this point in the history
…scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

- Finish merging initial SDT (Statically Defined Traces) support, see
  cset comments for details about how it all works (Masami Hiramatsu)

- Support attaching eBPF programs to tracepoints (Wang Nan)

Infrastructure changes:

- Fix up BITS_PER_LONG setting (Arnaldo Carvalho de Melo)

- Add fallback from ELF_C_READ_MMAP to ELF_C_READ in objtool, fixing
  the build in libelf implementations lacking that elf_begin() cmd,
  such as Alpine Linux's (Arnaldo Carvalho de Melo)

- Avoid checking code drift on busybox's diff in objtool (Arnaldo Carvalho de Melo)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Jul 14, 2016
2 parents 7b39caf + 8e5dc84 commit b29c657
Show file tree
Hide file tree
Showing 29 changed files with 850 additions and 112 deletions.
3 changes: 2 additions & 1 deletion tools/build/Makefile.feature
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ FEATURE_TESTS_BASIC := \
zlib \
lzma \
get_cpuid \
bpf
bpf \
sdt

# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
# of all feature tests
Expand Down
6 changes: 5 additions & 1 deletion tools/build/feature/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ FILES= \
test-zlib.bin \
test-lzma.bin \
test-bpf.bin \
test-get_cpuid.bin
test-get_cpuid.bin \
test-sdt.bin

FILES := $(addprefix $(OUTPUT),$(FILES))

Expand Down Expand Up @@ -213,6 +214,9 @@ $(OUTPUT)test-get_cpuid.bin:
$(OUTPUT)test-bpf.bin:
$(BUILD)

$(OUTPUT)test-sdt.bin:
$(BUILD)

-include $(OUTPUT)*.d

###############################
Expand Down
5 changes: 5 additions & 0 deletions tools/build/feature/test-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@
# include "test-libcrypto.c"
#undef main

#define main main_test_sdt
# include "test-sdt.c"
#undef main

int main(int argc, char *argv[])
{
main_test_libpython();
Expand Down Expand Up @@ -178,6 +182,7 @@ int main(int argc, char *argv[])
main_test_get_cpuid();
main_test_bpf();
main_test_libcrypto();
main_test_sdt();

return 0;
}
7 changes: 7 additions & 0 deletions tools/build/feature/test-sdt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <sys/sdt.h>

int main(void)
{
DTRACE_PROBE(provider, name);
return 0;
}
24 changes: 19 additions & 5 deletions tools/include/asm-generic/bitsperlong.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,32 @@

#include <uapi/asm-generic/bitsperlong.h>

/*
* In the kernel, where this file comes from, we can rely on CONFIG_64BIT,
* here we have to make amends with what the various compilers provides us
* to figure out if we're on a 64-bit machine...
*/
#ifdef __SIZEOF_LONG__
# if __SIZEOF_LONG__ == 8
# define CONFIG_64BIT
# endif
#else
# ifdef __WORDSIZE
# if __WORDSIZE == 64
# define CONFIG_64BIT
# endif
# else
# error Failed to determine BITS_PER_LONG value
# endif
#endif

#ifdef CONFIG_64BIT
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif /* CONFIG_64BIT */

/*
* FIXME: The check currently breaks x86-64 build, so it's
* temporarily disabled. Please fix x86-64 and reenable
*/
#if 0 && BITS_PER_LONG != __BITS_PER_LONG
#if BITS_PER_LONG != __BITS_PER_LONG
#error Inconsistent word size. Check asm/bitsperlong.h
#endif

Expand Down
80 changes: 66 additions & 14 deletions tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
[ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
[ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
[ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
[ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
};

int libbpf_strerror(int err, char *buf, size_t size)
Expand Down Expand Up @@ -158,6 +159,7 @@ struct bpf_program {
char *section_name;
struct bpf_insn *insns;
size_t insns_cnt;
enum bpf_prog_type type;

struct {
int insn_idx;
Expand Down Expand Up @@ -299,6 +301,7 @@ bpf_program__init(void *data, size_t size, char *name, int idx,
prog->idx = idx;
prog->instances.fds = NULL;
prog->instances.nr = -1;
prog->type = BPF_PROG_TYPE_KPROBE;

return 0;
errout:
Expand Down Expand Up @@ -894,8 +897,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
}

static int
load_program(struct bpf_insn *insns, int insns_cnt,
char *license, u32 kern_version, int *pfd)
load_program(enum bpf_prog_type type, struct bpf_insn *insns,
int insns_cnt, char *license, u32 kern_version, int *pfd)
{
int ret;
char *log_buf;
Expand All @@ -907,9 +910,8 @@ load_program(struct bpf_insn *insns, int insns_cnt,
if (!log_buf)
pr_warning("Alloc log buffer for bpf loader error, continue without log\n");

ret = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
insns_cnt, license, kern_version,
log_buf, BPF_LOG_BUF_SIZE);
ret = bpf_load_program(type, insns, insns_cnt, license,
kern_version, log_buf, BPF_LOG_BUF_SIZE);

if (ret >= 0) {
*pfd = ret;
Expand All @@ -925,15 +927,27 @@ load_program(struct bpf_insn *insns, int insns_cnt,
pr_warning("-- BEGIN DUMP LOG ---\n");
pr_warning("\n%s\n", log_buf);
pr_warning("-- END LOG --\n");
} else if (insns_cnt >= BPF_MAXINSNS) {
pr_warning("Program too large (%d insns), at most %d insns\n",
insns_cnt, BPF_MAXINSNS);
ret = -LIBBPF_ERRNO__PROG2BIG;
} else {
if (insns_cnt >= BPF_MAXINSNS) {
pr_warning("Program too large (%d insns), at most %d insns\n",
insns_cnt, BPF_MAXINSNS);
ret = -LIBBPF_ERRNO__PROG2BIG;
} else if (log_buf) {
pr_warning("log buffer is empty\n");
ret = -LIBBPF_ERRNO__KVER;
/* Wrong program type? */
if (type != BPF_PROG_TYPE_KPROBE) {
int fd;

fd = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
insns_cnt, license, kern_version,
NULL, 0);
if (fd >= 0) {
close(fd);
ret = -LIBBPF_ERRNO__PROGTYPE;
goto out;
}
}

if (log_buf)
ret = -LIBBPF_ERRNO__KVER;
}

out:
Expand Down Expand Up @@ -968,7 +982,7 @@ bpf_program__load(struct bpf_program *prog,
pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
prog->section_name, prog->instances.nr);
}
err = load_program(prog->insns, prog->insns_cnt,
err = load_program(prog->type, prog->insns, prog->insns_cnt,
license, kern_version, &fd);
if (!err)
prog->instances.fds[0] = fd;
Expand Down Expand Up @@ -997,7 +1011,7 @@ bpf_program__load(struct bpf_program *prog,
continue;
}

err = load_program(result.new_insn_ptr,
err = load_program(prog->type, result.new_insn_ptr,
result.new_insn_cnt,
license, kern_version, &fd);

Expand Down Expand Up @@ -1316,6 +1330,44 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n)
return fd;
}

static void bpf_program__set_type(struct bpf_program *prog,
enum bpf_prog_type type)
{
prog->type = type;
}

int bpf_program__set_tracepoint(struct bpf_program *prog)
{
if (!prog)
return -EINVAL;
bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
return 0;
}

int bpf_program__set_kprobe(struct bpf_program *prog)
{
if (!prog)
return -EINVAL;
bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
return 0;
}

static bool bpf_program__is_type(struct bpf_program *prog,
enum bpf_prog_type type)
{
return prog ? (prog->type == type) : false;
}

bool bpf_program__is_tracepoint(struct bpf_program *prog)
{
return bpf_program__is_type(prog, BPF_PROG_TYPE_TRACEPOINT);
}

bool bpf_program__is_kprobe(struct bpf_program *prog)
{
return bpf_program__is_type(prog, BPF_PROG_TYPE_KPROBE);
}

int bpf_map__fd(struct bpf_map *map)
{
return map ? map->fd : -EINVAL;
Expand Down
10 changes: 10 additions & 0 deletions tools/lib/bpf/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum libbpf_errno {
LIBBPF_ERRNO__VERIFY, /* Kernel verifier blocks program loading */
LIBBPF_ERRNO__PROG2BIG, /* Program too big */
LIBBPF_ERRNO__KVER, /* Incorrect kernel version */
LIBBPF_ERRNO__PROGTYPE, /* Kernel doesn't support this program type */
__LIBBPF_ERRNO__END,
};

Expand Down Expand Up @@ -164,6 +165,15 @@ int bpf_program__set_prep(struct bpf_program *prog, int nr_instance,

int bpf_program__nth_fd(struct bpf_program *prog, int n);

/*
* Adjust type of bpf program. Default is kprobe.
*/
int bpf_program__set_tracepoint(struct bpf_program *prog);
int bpf_program__set_kprobe(struct bpf_program *prog);

bool bpf_program__is_tracepoint(struct bpf_program *prog);
bool bpf_program__is_kprobe(struct bpf_program *prog);

/*
* We don't need __attribute__((packed)) now since it is
* unnecessary for 'bpf_map_def' because they are all aligned.
Expand Down
5 changes: 4 additions & 1 deletion tools/objtool/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ include $(srctree)/tools/build/Makefile.include
$(OBJTOOL_IN): fixdep FORCE
@$(MAKE) $(build)=objtool

# Busybox's diff doesn't have -I, avoid warning in that case
#
$(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
@(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
@(diff -I 2>&1 | grep -q 'option requires an argument' && \
test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
Expand Down
7 changes: 7 additions & 0 deletions tools/objtool/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
#include "elf.h"
#include "warn.h"

/*
* Fallback for systems without this "read, mmaping if possible" cmd.
*/
#ifndef ELF_C_READ_MMAP
#define ELF_C_READ_MMAP ELF_C_READ
#endif

struct section *find_section_by_name(struct elf *elf, const char *name)
{
struct section *sec;
Expand Down
11 changes: 10 additions & 1 deletion tools/perf/Documentation/perf-probe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,22 @@ Probe points are defined by following syntax.
3) Define event based on source file with lazy pattern
[[GROUP:]EVENT=]SRC;PTN [ARG ...]

4) Pre-defined SDT events or cached event with name
%[sdt_PROVIDER:]SDTEVENT
or,
sdt_PROVIDER:SDTEVENT

'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
modules.
'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events.

For details of the SDT, see below.
https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html

PROBE ARGUMENT
--------------
Expand Down Expand Up @@ -237,4 +246,4 @@ Add probes at malloc() function on libc

SEE ALSO
--------
linkperf:perf-trace[1], linkperf:perf-record[1]
linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
3 changes: 3 additions & 0 deletions tools/perf/Makefile.perf
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ include ../scripts/utilities.mak
#
# Define NO_LIBBPF if you do not want BPF support
#
# Define NO_SDT if you do not want to define SDT event in perf tools,
# note that it doesn't disable SDT scanning support.
#
# Define FEATURES_DUMP to provide features detection dump file
# and bypass the feature detection

Expand Down
6 changes: 5 additions & 1 deletion tools/perf/builtin-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_END()
};
const char * const list_usage[] = {
"perf list [hw|sw|cache|tracepoint|pmu|event_glob]",
"perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
NULL
};

Expand Down Expand Up @@ -62,6 +62,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
print_hwcache_events(NULL, raw_dump);
else if (strcmp(argv[i], "pmu") == 0)
print_pmu_events(NULL, raw_dump);
else if (strcmp(argv[i], "sdt") == 0)
print_sdt_events(NULL, NULL, raw_dump);
else if ((sep = strchr(argv[i], ':')) != NULL) {
int sep_idx;

Expand All @@ -76,6 +78,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)

s[sep_idx] = '\0';
print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
print_sdt_events(s, s + sep_idx + 1, raw_dump);
free(s);
} else {
if (asprintf(&s, "*%s*", argv[i]) < 0) {
Expand All @@ -89,6 +92,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
print_hwcache_events(s, raw_dump);
print_pmu_events(s, raw_dump);
print_tracepoint_events(NULL, s, raw_dump);
print_sdt_events(NULL, s, raw_dump);
free(s);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
struct str_node *nd;
int ret;

bidlist = build_id_cache__list_all();
bidlist = build_id_cache__list_all(false);
if (!bidlist) {
ret = -errno;
pr_debug("Failed to get buildids: %d\n", ret);
Expand Down
10 changes: 10 additions & 0 deletions tools/perf/config/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,16 @@ ifndef NO_LIBELF
endif # NO_LIBBPF
endif # NO_LIBELF

ifndef NO_SDT
ifneq ($(feature-sdt), 1)
msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev);
NO_SDT := 1;
else
CFLAGS += -DHAVE_SDT_EVENT
$(call detected,CONFIG_SDT_EVENT)
endif
endif

ifdef PERF_HAVE_JITDUMP
ifndef NO_DWARF
$(call detected,CONFIG_JITDUMP)
Expand Down
1 change: 1 addition & 0 deletions tools/perf/tests/Build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ perf-y += stat.o
perf-y += event_update.o
perf-y += event-times.o
perf-y += backward-ring-buffer.o
perf-y += sdt.o

$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
$(call rule_mkdir)
Expand Down
Loading

0 comments on commit b29c657

Please sign in to comment.