Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753533AbbEQLDZ (ORCPT ); Sun, 17 May 2015 07:03:25 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:26273 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753242AbbEQK5v (ORCPT ); Sun, 17 May 2015 06:57:51 -0400 From: Wang Nan To: , , , , , , , , , , CC: , , Subject: [RFC PATCH v3 21/37] bpf tools: Create eBPF maps defined in an object file Date: Sun, 17 May 2015 10:56:46 +0000 Message-ID: <1431860222-61636-22-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1431860222-61636-1-git-send-email-wangnan0@huawei.com> References: <1431860222-61636-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.200] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020203.5558741F.001E,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: b0bec0a933b7f2b683510fb3f488f015 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4157 Lines: 174 This patch creates maps based on 'map' section in object file using bpf_create_map(), and store the fds into an array in 'struct bpf_object'. Since the byte order of the object may differ from the host, swap map definition before processing. This is the first patch in 'loading' phase. Previous patches parse ELF object file and create needed data structure, but doesnnt play with kernel. They belong to 'opening' phase. Signed-off-by: Wang Nan --- tools/lib/bpf/libbpf.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf.h | 4 +++ 2 files changed, 102 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 9ed8cca..6ff4cb6 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -22,6 +22,7 @@ #include #include "libbpf.h" +#include "bpf.h" #ifdef min # undef min @@ -107,6 +108,7 @@ struct bpf_object { struct bpf_program *programs; size_t nr_programs; + int *maps_fds; /* * Information when doing elf related work. Only valid if fd @@ -613,6 +615,67 @@ bpf_program_collect_reloc(struct bpf_object *obj, return 0; } +static int +bpf_obj_create_maps(struct bpf_object *obj) +{ + unsigned int i; + size_t nr_maps; + int *pfd; + + nr_maps = obj->maps_buf_sz / sizeof(struct bpf_map_def); + if (!obj->maps_buf || !nr_maps) { + pr_debug("don't need create maps for %s\n", + obj->path); + return 0; + } + + obj->maps_fds = malloc(sizeof(int) * nr_maps); + if (!obj->maps_fds) { + pr_warning("realloc perf_bpf_maps_fds failed\n"); + return -ENOMEM; + } + + /* fill all fd with -1 */ + memset(obj->maps_fds, 0xff, sizeof(int) * nr_maps); + + pfd = obj->maps_fds; + for (i = 0; i < nr_maps; i++) { + struct bpf_map_def def; + + def = *(struct bpf_map_def *)(obj->maps_buf + + i * sizeof(struct bpf_map_def)); + + if (obj->needs_swap) { + def.type = bswap_32(def.type); + def.key_size = bswap_32(def.key_size); + def.value_size = bswap_32(def.value_size); + def.max_entries = bswap_32(def.max_entries); + } + + *pfd = bpf_create_map(def.type, + def.key_size, + def.value_size, + def.max_entries); + if (*pfd < 0) { + size_t j; + int err = *pfd; + + pr_warning("failed to create map: %s\n", + strerror(errno)); + for (j = 0; j < i; j++) { + close(obj->maps_fds[j]); + obj->maps_fds[j] = -1; + } + free(obj->maps_fds); + obj->maps_fds = NULL; + return err; + } + pr_debug("create map: fd=%d\n", *pfd); + pfd ++; + } + return 0; +} + static int bpf_obj_collect_reloc(struct bpf_object *obj) { int i, err; @@ -694,12 +757,47 @@ out: return NULL; } +int bpf_unload_object(struct bpf_object *obj) +{ + if (!obj) + return -EINVAL; + + if (obj->maps_fds) { + size_t i; + size_t sz = sizeof(struct bpf_map_def); + + for (i = 0; i < obj->maps_buf_sz; i += sz) { + if (obj->maps_fds[i] >= 0) + close(obj->maps_fds[i]); + } + free(obj->maps_fds); + } + + return 0; +} + +int bpf_load_object(struct bpf_object *obj) +{ + if (!obj) + return -EINVAL; + + if (bpf_obj_create_maps(obj)) + goto out; + + return 0; +out: + bpf_unload_object(obj); + pr_warning("failed to load object '%s'\n", obj->path); + return -EINVAL; +} + void bpf_close_object(struct bpf_object *obj) { if (!obj) return; bpf_obj_clear_elf(obj); + bpf_unload_object(obj); if (obj->path) free(obj->path); diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 3505be7..c0b290d 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -21,6 +21,10 @@ struct bpf_object; struct bpf_object *bpf_open_object(const char *path); void bpf_close_object(struct bpf_object *object); +/* Load/unload object into/from kernel */ +int bpf_load_object(struct bpf_object *obj); +int bpf_unload_object(struct bpf_object *obj); + /* * packed attribute is unnecessary for 'bpf_map_def'. */ -- 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/