aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/libbpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r--tools/lib/bpf/libbpf.c87
1 files changed, 46 insertions, 41 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 955f8eafbf41..26e9527ee464 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -37,6 +37,7 @@
37#include <linux/err.h> 37#include <linux/err.h>
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <linux/bpf.h> 39#include <linux/bpf.h>
40#include <linux/btf.h>
40#include <linux/list.h> 41#include <linux/list.h>
41#include <linux/limits.h> 42#include <linux/limits.h>
42#include <sys/stat.h> 43#include <sys/stat.h>
@@ -170,8 +171,8 @@ struct bpf_map {
170 size_t offset; 171 size_t offset;
171 int map_ifindex; 172 int map_ifindex;
172 struct bpf_map_def def; 173 struct bpf_map_def def;
173 uint32_t btf_key_type_id; 174 __u32 btf_key_type_id;
174 uint32_t btf_value_type_id; 175 __u32 btf_value_type_id;
175 void *priv; 176 void *priv;
176 bpf_map_clear_priv_t clear_priv; 177 bpf_map_clear_priv_t clear_priv;
177}; 178};
@@ -969,68 +970,72 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
969 970
970static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) 971static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
971{ 972{
973 const struct btf_type *container_type;
974 const struct btf_member *key, *value;
972 struct bpf_map_def *def = &map->def; 975 struct bpf_map_def *def = &map->def;
973 const size_t max_name = 256; 976 const size_t max_name = 256;
974 int64_t key_size, value_size; 977 char container_name[max_name];
975 int32_t key_id, value_id; 978 __s64 key_size, value_size;
976 char name[max_name]; 979 __s32 container_id;
977 980
978 /* Find key type by name from BTF */ 981 if (snprintf(container_name, max_name, "____btf_map_%s", map->name) ==
979 if (snprintf(name, max_name, "%s_key", map->name) == max_name) { 982 max_name) {
980 pr_warning("map:%s length of BTF key_type:%s_key is too long\n", 983 pr_warning("map:%s length of '____btf_map_%s' is too long\n",
981 map->name, map->name); 984 map->name, map->name);
982 return -EINVAL; 985 return -EINVAL;
983 } 986 }
984 987
985 key_id = btf__find_by_name(btf, name); 988 container_id = btf__find_by_name(btf, container_name);
986 if (key_id < 0) { 989 if (container_id < 0) {
987 pr_debug("map:%s key_type:%s cannot be found in BTF\n", 990 pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
988 map->name, name); 991 map->name, container_name);
989 return key_id; 992 return container_id;
990 } 993 }
991 994
992 key_size = btf__resolve_size(btf, key_id); 995 container_type = btf__type_by_id(btf, container_id);
993 if (key_size < 0) { 996 if (!container_type) {
994 pr_warning("map:%s key_type:%s cannot get the BTF type_size\n", 997 pr_warning("map:%s cannot find BTF type for container_id:%u\n",
995 map->name, name); 998 map->name, container_id);
996 return key_size; 999 return -EINVAL;
997 } 1000 }
998 1001
999 if (def->key_size != key_size) { 1002 if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
1000 pr_warning("map:%s key_type:%s has BTF type_size:%u != key_size:%u\n", 1003 BTF_INFO_VLEN(container_type->info) < 2) {
1001 map->name, name, (unsigned int)key_size, def->key_size); 1004 pr_warning("map:%s container_name:%s is an invalid container struct\n",
1005 map->name, container_name);
1002 return -EINVAL; 1006 return -EINVAL;
1003 } 1007 }
1004 1008
1005 /* Find value type from BTF */ 1009 key = (struct btf_member *)(container_type + 1);
1006 if (snprintf(name, max_name, "%s_value", map->name) == max_name) { 1010 value = key + 1;
1007 pr_warning("map:%s length of BTF value_type:%s_value is too long\n", 1011
1008 map->name, map->name); 1012 key_size = btf__resolve_size(btf, key->type);
1009 return -EINVAL; 1013 if (key_size < 0) {
1014 pr_warning("map:%s invalid BTF key_type_size\n",
1015 map->name);
1016 return key_size;
1010 } 1017 }
1011 1018
1012 value_id = btf__find_by_name(btf, name); 1019 if (def->key_size != key_size) {
1013 if (value_id < 0) { 1020 pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
1014 pr_debug("map:%s value_type:%s cannot be found in BTF\n", 1021 map->name, (__u32)key_size, def->key_size);
1015 map->name, name); 1022 return -EINVAL;
1016 return value_id;
1017 } 1023 }
1018 1024
1019 value_size = btf__resolve_size(btf, value_id); 1025 value_size = btf__resolve_size(btf, value->type);
1020 if (value_size < 0) { 1026 if (value_size < 0) {
1021 pr_warning("map:%s value_type:%s cannot get the BTF type_size\n", 1027 pr_warning("map:%s invalid BTF value_type_size\n", map->name);
1022 map->name, name);
1023 return value_size; 1028 return value_size;
1024 } 1029 }
1025 1030
1026 if (def->value_size != value_size) { 1031 if (def->value_size != value_size) {
1027 pr_warning("map:%s value_type:%s has BTF type_size:%u != value_size:%u\n", 1032 pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
1028 map->name, name, (unsigned int)value_size, def->value_size); 1033 map->name, (__u32)value_size, def->value_size);
1029 return -EINVAL; 1034 return -EINVAL;
1030 } 1035 }
1031 1036
1032 map->btf_key_type_id = key_id; 1037 map->btf_key_type_id = key->type;
1033 map->btf_value_type_id = value_id; 1038 map->btf_value_type_id = value->type;
1034 1039
1035 return 0; 1040 return 0;
1036} 1041}
@@ -2141,12 +2146,12 @@ const char *bpf_map__name(struct bpf_map *map)
2141 return map ? map->name : NULL; 2146 return map ? map->name : NULL;
2142} 2147}
2143 2148
2144uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map) 2149__u32 bpf_map__btf_key_type_id(const struct bpf_map *map)
2145{ 2150{
2146 return map ? map->btf_key_type_id : 0; 2151 return map ? map->btf_key_type_id : 0;
2147} 2152}
2148 2153
2149uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map) 2154__u32 bpf_map__btf_value_type_id(const struct bpf_map *map)
2150{ 2155{
2151 return map ? map->btf_value_type_id : 0; 2156 return map ? map->btf_value_type_id : 0;
2152} 2157}
@@ -2333,8 +2338,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
2333 volatile struct perf_event_mmap_page *header = mem; 2338 volatile struct perf_event_mmap_page *header = mem;
2334 __u64 data_tail = header->data_tail; 2339 __u64 data_tail = header->data_tail;
2335 __u64 data_head = header->data_head; 2340 __u64 data_head = header->data_head;
2341 int ret = LIBBPF_PERF_EVENT_ERROR;
2336 void *base, *begin, *end; 2342 void *base, *begin, *end;
2337 int ret;
2338 2343
2339 asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */ 2344 asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */
2340 if (data_head == data_tail) 2345 if (data_head == data_tail)