lkml.org 
[lkml]   [2015]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:perf/core] bpf tools: Load eBPF programs in object files into kernel
    Commit-ID:  55cffde2e1a41109cb49f8e94de954c8240242b5
    Gitweb: http://git.kernel.org/tip/55cffde2e1a41109cb49f8e94de954c8240242b5
    Author: Wang Nan <wangnan0@huawei.com>
    AuthorDate: Wed, 1 Jul 2015 02:14:07 +0000
    Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
    CommitDate: Fri, 7 Aug 2015 10:16:59 -0300

    bpf tools: Load eBPF programs in object files into kernel

    This patch utilizes previous introduced bpf_load_program to load
    programs in the ELF file into kernel. Result is stored in 'fd' field in
    'struct bpf_program'.

    During loading, it allocs a log buffer and free it before return. Note
    that that buffer is not passed to bpf_load_program() if the first
    loading try is successful. Doesn't use a statically allocated log buffer
    to avoid potention multi-thread problem.

    Instructions collected during opening is cleared after loading.

    load_program() is created for loading a 'struct bpf_insn' array into
    kernel, bpf_program__load() calls it. By this design we have a function
    loads instructions into kernel. It will be used by further patches,
    which creates different instances from a program and load them into
    kernel.

    Signed-off-by: Wang Nan <wangnan0@huawei.com>
    Acked-by: 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/1435716878-189507-20-git-send-email-wangnan0@huawei.com
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    ---
    tools/lib/bpf/libbpf.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 90 insertions(+)

    diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
    index 94f9660..38447b7 100644
    --- a/tools/lib/bpf/libbpf.c
    +++ b/tools/lib/bpf/libbpf.c
    @@ -96,6 +96,8 @@ struct bpf_program {
    int map_idx;
    } *reloc_desc;
    int nr_reloc;
    +
    + int fd;
    };

    struct bpf_object {
    @@ -135,11 +137,20 @@ struct bpf_object {
    };
    #define obj_elf_valid(o) ((o)->efile.elf)

    +static void bpf_program__unload(struct bpf_program *prog)
    +{
    + if (!prog)
    + return;
    +
    + zclose(prog->fd);
    +}
    +
    static void bpf_program__exit(struct bpf_program *prog)
    {
    if (!prog)
    return;

    + bpf_program__unload(prog);
    zfree(&prog->section_name);
    zfree(&prog->insns);
    zfree(&prog->reloc_desc);
    @@ -176,6 +187,7 @@ bpf_program__init(void *data, size_t size, char *name, int idx,
    memcpy(prog->insns, data,
    prog->insns_cnt * sizeof(struct bpf_insn));
    prog->idx = idx;
    + prog->fd = -1;

    return 0;
    errout:
    @@ -718,6 +730,79 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
    return 0;
    }

    +static int
    +load_program(struct bpf_insn *insns, int insns_cnt,
    + char *license, u32 kern_version, int *pfd)
    +{
    + int ret;
    + char *log_buf;
    +
    + if (!insns || !insns_cnt)
    + return -EINVAL;
    +
    + log_buf = malloc(BPF_LOG_BUF_SIZE);
    + 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);
    +
    + if (ret >= 0) {
    + *pfd = ret;
    + ret = 0;
    + goto out;
    + }
    +
    + ret = -EINVAL;
    + pr_warning("load bpf program failed: %s\n", strerror(errno));
    +
    + if (log_buf) {
    + pr_warning("-- BEGIN DUMP LOG ---\n");
    + pr_warning("\n%s\n", log_buf);
    + pr_warning("-- END LOG --\n");
    + }
    +
    +out:
    + free(log_buf);
    + return ret;
    +}
    +
    +static int
    +bpf_program__load(struct bpf_program *prog,
    + char *license, u32 kern_version)
    +{
    + int err, fd;
    +
    + err = load_program(prog->insns, prog->insns_cnt,
    + license, kern_version, &fd);
    + if (!err)
    + prog->fd = fd;
    +
    + if (err)
    + pr_warning("failed to load program '%s'\n",
    + prog->section_name);
    + zfree(&prog->insns);
    + prog->insns_cnt = 0;
    + return err;
    +}
    +
    +static int
    +bpf_object__load_progs(struct bpf_object *obj)
    +{
    + size_t i;
    + int err;
    +
    + for (i = 0; i < obj->nr_programs; i++) {
    + err = bpf_program__load(&obj->programs[i],
    + obj->license,
    + obj->kern_version);
    + if (err)
    + return err;
    + }
    + return 0;
    +}
    +
    static int bpf_object__validate(struct bpf_object *obj)
    {
    if (obj->kern_version == 0) {
    @@ -795,6 +880,9 @@ int bpf_object__unload(struct bpf_object *obj)
    zfree(&obj->map_fds);
    obj->nr_map_fds = 0;

    + for (i = 0; i < obj->nr_programs; i++)
    + bpf_program__unload(&obj->programs[i]);
    +
    return 0;
    }

    @@ -813,6 +901,8 @@ int bpf_object__load(struct bpf_object *obj)
    goto out;
    if (bpf_object__relocate(obj))
    goto out;
    + if (bpf_object__load_progs(obj))
    + goto out;

    return 0;
    out:

    \
     
     \ /
      Last update: 2015-08-08 10:41    [W:2.321 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site