aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-06-30 22:14:04 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-08-07 09:16:58 -0400
commit52d3352e79815307521bef6121dba00b6c3477c6 (patch)
treefd7c73f188c64066f4ff2a97dd0af6508f068f86
parente3ed2fef22b694cf07b06abaa6481a9e6f868e1f (diff)
bpf tools: Create eBPF maps defined in an object file
This patch creates maps based on 'map' section in object file using bpf_create_map(), and stores the fds into an array in 'struct bpf_object'. Previous patches parse ELF object file and collects required data, but doesn't play with the kernel. They belong to the 'opening' phase. This patch is the first patch in 'loading' phase. The 'loaded' field is introduced in 'struct bpf_object' to avoid loading an object twice, because the loading phase clears resources collected during the opening which becomes useless after loading. In this patch, maps_buf is cleared. 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-17-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/lib/bpf/libbpf.c102
-rw-r--r--tools/lib/bpf/libbpf.h4
2 files changed, 106 insertions, 0 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index ac69ae3bd628..54b48de3df78 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -21,6 +21,7 @@
21#include <gelf.h> 21#include <gelf.h>
22 22
23#include "libbpf.h" 23#include "libbpf.h"
24#include "bpf.h"
24 25
25#define __printf(a, b) __attribute__((format(printf, a, b))) 26#define __printf(a, b) __attribute__((format(printf, a, b)))
26 27
@@ -105,6 +106,13 @@ struct bpf_object {
105 106
106 struct bpf_program *programs; 107 struct bpf_program *programs;
107 size_t nr_programs; 108 size_t nr_programs;
109 int *map_fds;
110 /*
111 * This field is required because maps_buf will be freed and
112 * maps_buf_sz will be set to 0 after loaded.
113 */
114 size_t nr_map_fds;
115 bool loaded;
108 116
109 /* 117 /*
110 * Information when doing elf related work. Only valid if fd 118 * Information when doing elf related work. Only valid if fd
@@ -233,6 +241,7 @@ static struct bpf_object *bpf_object__new(const char *path,
233 obj->efile.obj_buf = obj_buf; 241 obj->efile.obj_buf = obj_buf;
234 obj->efile.obj_buf_sz = obj_buf_sz; 242 obj->efile.obj_buf_sz = obj_buf_sz;
235 243
244 obj->loaded = false;
236 return obj; 245 return obj;
237} 246}
238 247
@@ -565,6 +574,62 @@ bpf_program__collect_reloc(struct bpf_program *prog,
565 return 0; 574 return 0;
566} 575}
567 576
577static int
578bpf_object__create_maps(struct bpf_object *obj)
579{
580 unsigned int i;
581 size_t nr_maps;
582 int *pfd;
583
584 nr_maps = obj->maps_buf_sz / sizeof(struct bpf_map_def);
585 if (!obj->maps_buf || !nr_maps) {
586 pr_debug("don't need create maps for %s\n",
587 obj->path);
588 return 0;
589 }
590
591 obj->map_fds = malloc(sizeof(int) * nr_maps);
592 if (!obj->map_fds) {
593 pr_warning("realloc perf_bpf_map_fds failed\n");
594 return -ENOMEM;
595 }
596 obj->nr_map_fds = nr_maps;
597
598 /* fill all fd with -1 */
599 memset(obj->map_fds, -1, sizeof(int) * nr_maps);
600
601 pfd = obj->map_fds;
602 for (i = 0; i < nr_maps; i++) {
603 struct bpf_map_def def;
604
605 def = *(struct bpf_map_def *)(obj->maps_buf +
606 i * sizeof(struct bpf_map_def));
607
608 *pfd = bpf_create_map(def.type,
609 def.key_size,
610 def.value_size,
611 def.max_entries);
612 if (*pfd < 0) {
613 size_t j;
614 int err = *pfd;
615
616 pr_warning("failed to create map: %s\n",
617 strerror(errno));
618 for (j = 0; j < i; j++)
619 zclose(obj->map_fds[j]);
620 obj->nr_map_fds = 0;
621 zfree(&obj->map_fds);
622 return err;
623 }
624 pr_debug("create map: fd=%d\n", *pfd);
625 pfd++;
626 }
627
628 zfree(&obj->maps_buf);
629 obj->maps_buf_sz = 0;
630 return 0;
631}
632
568static int bpf_object__collect_reloc(struct bpf_object *obj) 633static int bpf_object__collect_reloc(struct bpf_object *obj)
569{ 634{
570 int i, err; 635 int i, err;
@@ -668,6 +733,42 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf,
668 return __bpf_object__open("[buffer]", obj_buf, obj_buf_sz); 733 return __bpf_object__open("[buffer]", obj_buf, obj_buf_sz);
669} 734}
670 735
736int bpf_object__unload(struct bpf_object *obj)
737{
738 size_t i;
739
740 if (!obj)
741 return -EINVAL;
742
743 for (i = 0; i < obj->nr_map_fds; i++)
744 zclose(obj->map_fds[i]);
745 zfree(&obj->map_fds);
746 obj->nr_map_fds = 0;
747
748 return 0;
749}
750
751int bpf_object__load(struct bpf_object *obj)
752{
753 if (!obj)
754 return -EINVAL;
755
756 if (obj->loaded) {
757 pr_warning("object should not be loaded twice\n");
758 return -EINVAL;
759 }
760
761 obj->loaded = true;
762 if (bpf_object__create_maps(obj))
763 goto out;
764
765 return 0;
766out:
767 bpf_object__unload(obj);
768 pr_warning("failed to load object '%s'\n", obj->path);
769 return -EINVAL;
770}
771
671void bpf_object__close(struct bpf_object *obj) 772void bpf_object__close(struct bpf_object *obj)
672{ 773{
673 size_t i; 774 size_t i;
@@ -676,6 +777,7 @@ void bpf_object__close(struct bpf_object *obj)
676 return; 777 return;
677 778
678 bpf_object__elf_finish(obj); 779 bpf_object__elf_finish(obj);
780 bpf_object__unload(obj);
679 781
680 zfree(&obj->maps_buf); 782 zfree(&obj->maps_buf);
681 783
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 6e75acdb9112..3e6960075835 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -30,6 +30,10 @@ struct bpf_object *bpf_object__open_buffer(void *obj_buf,
30 size_t obj_buf_sz); 30 size_t obj_buf_sz);
31void bpf_object__close(struct bpf_object *object); 31void bpf_object__close(struct bpf_object *object);
32 32
33/* Load/unload object into/from kernel */
34int bpf_object__load(struct bpf_object *obj);
35int bpf_object__unload(struct bpf_object *obj);
36
33/* 37/*
34 * We don't need __attribute__((packed)) now since it is 38 * We don't need __attribute__((packed)) now since it is
35 * unnecessary for 'bpf_map_def' because they are all aligned. 39 * unnecessary for 'bpf_map_def' because they are all aligned.