Re: [PATCH v3 bpf 3/3] bpf: Introduce BPF_ANNOTATE_KV_PAIR

2018-07-24 Thread Yonghong Song




On 7/24/18 8:40 AM, Martin KaFai Lau wrote:

This patch introduces BPF_ANNOTATE_KV_PAIR to signal the
bpf loader about the btf key_type and value_type of a bpf map.
Please refer to the changes in test_btf_haskv.c for its usage.
Both iproute2 and libbpf loader will then have the same
convention to find out the map's btf_key_type_id and
btf_value_type_id from a map's name.

Fixes: 8a138aed4a80 ("bpf: btf: Add BTF support to libbpf")
Suggested-by: Daniel Borkmann 
Signed-off-by: Martin KaFai Lau 


Acked-by: Yonghong Song 


[PATCH v3 bpf 3/3] bpf: Introduce BPF_ANNOTATE_KV_PAIR

2018-07-24 Thread Martin KaFai Lau
This patch introduces BPF_ANNOTATE_KV_PAIR to signal the
bpf loader about the btf key_type and value_type of a bpf map.
Please refer to the changes in test_btf_haskv.c for its usage.
Both iproute2 and libbpf loader will then have the same
convention to find out the map's btf_key_type_id and
btf_value_type_id from a map's name.

Fixes: 8a138aed4a80 ("bpf: btf: Add BTF support to libbpf")
Suggested-by: Daniel Borkmann 
Signed-off-by: Martin KaFai Lau 
---
 tools/lib/bpf/btf.c  |  7 +-
 tools/lib/bpf/btf.h  |  2 +
 tools/lib/bpf/libbpf.c   | 75 +++-
 tools/testing/selftests/bpf/bpf_helpers.h|  9 +++
 tools/testing/selftests/bpf/test_btf_haskv.c |  7 +-
 5 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index b80de80b4584..2d270c560df3 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -189,8 +189,7 @@ static int btf_parse_type_sec(struct btf *btf, 
btf_print_fn_t err_log)
return 0;
 }
 
-static const struct btf_type *btf_type_by_id(const struct btf *btf,
-__u32 type_id)
+const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
 {
if (type_id > btf->nr_types)
return NULL;
@@ -233,7 +232,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 
type_id)
__s64 size = -1;
int i;
 
-   t = btf_type_by_id(btf, type_id);
+   t = btf__type_by_id(btf, type_id);
for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
 i++) {
size = btf_type_size(t);
@@ -258,7 +257,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 
type_id)
return -EINVAL;
}
 
-   t = btf_type_by_id(btf, type_id);
+   t = btf__type_by_id(btf, type_id);
}
 
if (size < 0)
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index ed3a84370ccc..e2a09a155f84 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -9,6 +9,7 @@
 #define BTF_ELF_SEC ".BTF"
 
 struct btf;
+struct btf_type;
 
 typedef int (*btf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2)));
@@ -16,6 +17,7 @@ typedef int (*btf_print_fn_t)(const char *, ...)
 void btf__free(struct btf *btf);
 struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
 __s32 btf__find_by_name(const struct btf *btf, const char *type_name);
+const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id);
 __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
 int btf__fd(const struct btf *btf);
 
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 6deb4fe4fffe..d881d370616c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1014,68 +1015,72 @@ bpf_program__collect_reloc(struct bpf_program *prog, 
GElf_Shdr *shdr,
 
 static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
 {
+   const struct btf_type *container_type;
+   const struct btf_member *key, *value;
struct bpf_map_def *def = >def;
const size_t max_name = 256;
+   char container_name[max_name];
__s64 key_size, value_size;
-   __s32 key_id, value_id;
-   char name[max_name];
+   __s32 container_id;
 
-   /* Find key type by name from BTF */
-   if (snprintf(name, max_name, "%s_key", map->name) == max_name) {
-   pr_warning("map:%s length of BTF key_type:%s_key is too long\n",
+   if (snprintf(container_name, max_name, "btf_map_%s", map->name) ==
+   max_name) {
+   pr_warning("map:%s length of 'btf_map_%s' is too long\n",
   map->name, map->name);
return -EINVAL;
}
 
-   key_id = btf__find_by_name(btf, name);
-   if (key_id < 0) {
-   pr_debug("map:%s key_type:%s cannot be found in BTF\n",
-map->name, name);
-   return key_id;
+   container_id = btf__find_by_name(btf, container_name);
+   if (container_id < 0) {
+   pr_debug("map:%s container_name:%s cannot be found in BTF. 
Missing BPF_ANNOTATE_KV_PAIR?\n",
+map->name, container_name);
+   return container_id;
}
 
-   key_size = btf__resolve_size(btf, key_id);
-   if (key_size < 0) {
-   pr_warning("map:%s key_type:%s cannot get the BTF type_size\n",
-  map->name, name);
-   return key_size;
+   container_type = btf__type_by_id(btf, container_id);
+   if (!container_type) {
+   pr_warning("map:%s cannot find BTF type for container_id:%u\n",
+  map->name, container_id);
+   return -EINVAL;
}
 
-   if