Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932282AbbGGPSJ (ORCPT ); Tue, 7 Jul 2015 11:18:09 -0400 Received: from mail.kernel.org ([198.145.29.136]:53788 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757093AbbGGPSB (ORCPT ); Tue, 7 Jul 2015 11:18:01 -0400 Date: Tue, 7 Jul 2015 12:17:56 -0300 From: Arnaldo Carvalho de Melo To: Wang Nan Cc: ast@plumgrid.com, brendan.d.gregg@gmail.com, daniel@iogearbox.net, namhyung@kernel.org, masami.hiramatsu.pt@hitachi.com, paulus@samba.org, a.p.zijlstra@chello.nl, mingo@redhat.com, jolsa@kernel.org, dsahern@gmail.com, linux-kernel@vger.kernel.org, lizefan@huawei.com, hekuang@huawei.com, xiakaixu@huawei.com, pi3orama@163.com Subject: Re: [RFC PATCH v10 12/50] bpf tools: Collect eBPF programs from their own sections Message-ID: <20150707151756.GK3326@kernel.org> References: <1435716878-189507-1-git-send-email-wangnan0@huawei.com> <1435716878-189507-13-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1435716878-189507-13-git-send-email-wangnan0@huawei.com> X-Url: http://acmel.wordpress.com User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5293 Lines: 191 Em Wed, Jul 01, 2015 at 02:14:00AM +0000, Wang Nan escreveu: > This patch collects all programs in an object file into an array of > 'struct bpf_program' for further processing. That structure is for > representing each eBPF program. 'bpf_prog' should be a better name, but > it has been used by linux/filter.h. Although it is a kernel space name, > I still prefer to call it 'bpf_program' to prevent possible confusion. > > Signed-off-by: Wang Nan > Acked-by: Alexei Starovoitov > --- > tools/lib/bpf/libbpf.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 107 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 9b016c0..9c01b55f 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -78,12 +78,27 @@ void libbpf_set_print(libbpf_print_fn_t warn, > # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ > #endif > > +/* > + * bpf_prog should be a better name but it has been used in > + * linux/filter.h. > + */ > +struct bpf_program { > + /* Index in elf obj file, for relocation use. */ > + int idx; > + char *section_name; > + struct bpf_insn *insns; > + size_t insns_cnt; > +}; > + > struct bpf_object { > char license[64]; > u32 kern_version; > void *maps_buf; > size_t maps_buf_sz; > > + struct bpf_program *programs; > + size_t nr_programs; > + > /* > * Information when doing elf related work. Only valid if fd > * is valid. > @@ -100,6 +115,74 @@ struct bpf_object { > }; > #define obj_elf_valid(o) ((o)->efile.elf) > > +static void bpf_program__clear(struct bpf_program *prog) > +{ > + if (!prog) > + return; > + > + zfree(&prog->section_name); > + zfree(&prog->insns); > + prog->insns_cnt = 0; > + prog->idx = -1; > +} > + > +static struct bpf_program * > +bpf_program__new(struct bpf_object *obj, void *data, size_t size, > + char *name, int idx) > +{ > + struct bpf_program *prog, *progs; > + int nr_progs; > + > + if (size < sizeof(struct bpf_insn)) { > + pr_warning("corrupted section '%s'\n", name); > + return NULL; > + } > + > + progs = obj->programs; > + nr_progs = obj->nr_programs; > + > + progs = realloc(progs, sizeof(*prog) * (nr_progs + 1)); > + if (!progs) { > + /* > + * In this case the original obj->programs > + * is still valid, so don't need special treat for > + * bpf_close_object(). > + */ > + pr_warning("failed to alloc a new program '%s'\n", > + name); > + return NULL; > + } > + > + obj->programs = progs; > + > + prog = &progs[nr_progs]; > + bzero(prog, sizeof(*prog)); > + > + obj->nr_programs = nr_progs + 1; So here you basically commited your allocator, i.e. obj->nr_programs now includes one extra program, but... > + prog->section_name = strdup(name); > + if (!prog->section_name) { > + pr_warning("failed to alloc name for prog %s\n", > + name); > + goto out; Here, that BTW could be better named "goto out_clear", you bail out by calling... > + } > + > + prog->insns = malloc(size); > + if (!prog->insns) { > + pr_warning("failed to alloc insns for %s\n", name); > + goto out; > + } > + prog->insns_cnt = size / sizeof(struct bpf_insn); > + memcpy(prog->insns, data, > + prog->insns_cnt * sizeof(struct bpf_insn)); > + prog->idx = idx; > + > + return prog; > +out: ... bpf_program__clear(), that will not reduce the number of entries in obj->nr_programs, how will you garbage collect the unused entries? Why not decouple bpf_program__new() from bpf_object? I.e. you call it it will allocate space for a new bpf_program, if all goes well, you then insert it into that bpf_object instance, no? Even with this problem, I am applying it to my local tree to continue looking at the other patches and to test the end result. - Arnaldo > + bpf_program__clear(prog); > + return NULL; > +} > + > static struct bpf_object *bpf_object__new(const char *path, > void *obj_buf, > size_t obj_buf_sz) > @@ -342,6 +425,21 @@ static int bpf_object__elf_collect(struct bpf_object *obj) > err = -EEXIST; > } else > obj->efile.symbols = data; > + } else if ((sh.sh_type == SHT_PROGBITS) && > + (sh.sh_flags & SHF_EXECINSTR) && > + (data->d_size > 0)) { > + struct bpf_program *prog; > + > + prog = bpf_program__new(obj, data->d_buf, > + data->d_size, name, > + idx); > + if (!prog) { > + pr_warning("failed to alloc program %s (%s)", > + name, obj->path); > + err = -ENOMEM; > + } else > + pr_debug("found program %s\n", > + prog->section_name); > } > if (err) > goto out; > @@ -415,11 +513,20 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf, > > void bpf_object__close(struct bpf_object *obj) > { > + size_t i; > + > if (!obj) > return; > > bpf_object__elf_finish(obj); > > zfree(&obj->maps_buf); > + > + if (obj->programs && obj->nr_programs) { > + for (i = 0; i < obj->nr_programs; i++) > + bpf_program__clear(&obj->programs[i]); > + } > + zfree(&obj->programs); > + > free(obj); > } > -- > 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/