• Wang Nan's avatar
    perf tools: Create probe points for BPF programs · aa3abf30
    Wang Nan authored
    This patch introduces bpf__{un,}probe() functions to enable callers to
    create kprobe points based on section names a BPF program. It parses the
    section names in the program and creates corresponding 'struct
    perf_probe_event' structures. The parse_perf_probe_command() function is
    used to do the main parsing work. The resuling 'struct perf_probe_event'
    is stored into program private data for further using.
    
    By utilizing the new probing API, this patch creates probe points during
    event parsing.
    
    To ensure probe points be removed correctly, register an atexit hook so
    even perf quit through exit() bpf__clear() is still called, so probing
    points are cleared. Note that bpf_clear() should be registered before
    bpf__probe() is called, so failure of bpf__probe() can still trigger
    bpf__clear() to remove probe points which are already probed.
    
    strerror style error reporting scaffold is created by this patch.
    bpf__strerror_probe() is the first error reporting function in
    bpf-loader.c.
    
    Committer note:
    
    Trying it:
    
    To build a test eBPF object file:
    
    I am testing using a script I built from the 'perf test -v LLVM' output:
    
      $ cat ~/bin/hello-ebpf
      export KERNEL_INC_OPTIONS="-nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.3/include -I/home/acme/git/linux/arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated -I/home/acme/git/linux/include -Iinclude -I/home/acme/git/linux/arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I/home/acme/git/linux/include/uapi -Iinclude/generated/uapi -include /home/acme/git/linux/include/linux/kconfig.h"
      export WORKING_DIR=/lib/modules/4.2.0/build
      export CLANG_SOURCE=-
      export CLANG_OPTIONS=-xc
    
      OBJ=/tmp/foo.o
      rm -f $OBJ
      echo '__attribute__((section("fork=do_fork"), used)) int fork(void *ctx) {return 0;} char _license[] __attribute__((section("license"), used)) = "GPL";int _version __attribute__((section("version"), used)) = 0x40100;' | \
      clang -D__KERNEL__ $CLANG_OPTIONS $KERNEL_INC_OPTIONS -Wno-unused-value -Wno-pointer-sign -working-directory $WORKING_DIR -c "$CLANG_SOURCE" -target bpf -O2 -o /tmp/foo.o && file $OBJ
    
     ---
    
    First asking to put a probe in a function not present in the kernel
    (misses the initial _):
    
      $ perf record --event /tmp/foo.o sleep 1
      Probe point 'do_fork' not found.
      event syntax error: '/tmp/foo.o'
                           \___ You need to check probing points in BPF file
    
      (add -v to see detail)
      Run 'perf list' for a list of valid events
    
       Usage: perf record [<options>] [<command>]
          or: perf record [<options>] -- <command> [<options>]
    
          -e, --event <event>   event selector. use 'perf list' to list available events
      $
    
     ---
    
    Now, with "__attribute__((section("fork=_do_fork"), used)):
    
     $ grep _do_fork /proc/kallsyms
     ffffffff81099ab0 T _do_fork
     $ perf record --event /tmp/foo.o sleep 1
     Failed to open kprobe_events: Permission denied
     event syntax error: '/tmp/foo.o'
                          \___ Permission denied
    
     ---
    
    Cool, we need to provide some better hints, "kprobe_events" is too low
    level, one doesn't strictly need to know the precise details of how
    these things are put in place, so something that shows the command
    needed to fix the permissions would be more helpful.
    
    Lets try as root instead:
    
      # perf record --event /tmp/foo.o sleep 1
      Lowering default frequency rate to 1000.
      Please consider tweaking /proc/sys/kernel/perf_event_max_sample_rate.
      [ perf record: Woken up 1 times to write data ]
      [ perf record: Captured and wrote 0.013 MB perf.data ]
      # perf evlist
      /tmp/foo.o
      [root@felicio ~]# perf evlist -v
      /tmp/foo.o: type: 1, size: 112, config: 0x9, { sample_period,
      sample_freq }: 1000, sample_type: IP|TID|TIME|PERIOD, disabled: 1,
      inherit: 1, mmap: 1, comm: 1, freq: 1, enable_on_exec: 1, task: 1,
      sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
    
     ---
    Signed-off-by: default avatarWang Nan <wangnan0@huawei.com>
    Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Alexei Starovoitov <ast@plumgrid.com>
    Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
    Cc: Daniel Borkmann <daniel@iogearbox.net>
    Cc: David Ahern <dsahern@gmail.com>
    Cc: He Kuang <hekuang@huawei.com>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Kaixu Xia <xiakaixu@huawei.com>
    Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Zefan Li <lizefan@huawei.com>
    Cc: pi3orama@163.com
    Link: http://lkml.kernel.org/r/1444826502-49291-5-git-send-email-wangnan0@huawei.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    aa3abf30
bpf-loader.c 5.81 KB