diff options
author | David S. Miller <davem@davemloft.net> | 2018-08-02 13:55:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-02 13:55:32 -0400 |
commit | 89b1698c93a9dee043154f33d96bca9964e705f1 (patch) | |
tree | dd9dcb1965baae8edcf0b496aaa6a70609b6fc11 /tools/lib/bpf | |
parent | ffd7ce3cd9c294f1ff49ec02cdbd1bc7cb913db6 (diff) | |
parent | e30cb13c5a09ff5f043a6570c32e49b063bea6a1 (diff) |
Merge ra.kernel.org:/pub/scm/linux/kernel/git/davem/net
The BTF conflicts were simple overlapping changes.
The virtio_net conflict was an overlap of a fix of statistics counter,
happening alongisde a move over to a bonafide statistics structure
rather than counting value on the stack.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/lib/bpf')
-rw-r--r-- | tools/lib/bpf/btf.c | 46 | ||||
-rw-r--r-- | tools/lib/bpf/btf.h | 10 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.c | 87 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.h | 4 |
4 files changed, 84 insertions, 63 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 03161be094b4..1622a309f169 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* Copyright (c) 2018 Facebook */ | 2 | /* Copyright (c) 2018 Facebook */ |
3 | 3 | ||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <stdint.h> | ||
6 | #include <string.h> | 5 | #include <string.h> |
7 | #include <unistd.h> | 6 | #include <unistd.h> |
8 | #include <errno.h> | 7 | #include <errno.h> |
@@ -32,17 +31,25 @@ struct btf { | |||
32 | struct btf_type **types; | 31 | struct btf_type **types; |
33 | const char *strings; | 32 | const char *strings; |
34 | void *nohdr_data; | 33 | void *nohdr_data; |
35 | uint32_t nr_types; | 34 | __u32 nr_types; |
36 | uint32_t types_size; | 35 | __u32 types_size; |
37 | uint32_t data_size; | 36 | __u32 data_size; |
38 | int fd; | 37 | int fd; |
39 | }; | 38 | }; |
40 | 39 | ||
40 | static const char *btf_name_by_offset(const struct btf *btf, __u32 offset) | ||
41 | { | ||
42 | if (offset < btf->hdr->str_len) | ||
43 | return &btf->strings[offset]; | ||
44 | else | ||
45 | return NULL; | ||
46 | } | ||
47 | |||
41 | static int btf_add_type(struct btf *btf, struct btf_type *t) | 48 | static int btf_add_type(struct btf *btf, struct btf_type *t) |
42 | { | 49 | { |
43 | if (btf->types_size - btf->nr_types < 2) { | 50 | if (btf->types_size - btf->nr_types < 2) { |
44 | struct btf_type **new_types; | 51 | struct btf_type **new_types; |
45 | u32 expand_by, new_size; | 52 | __u32 expand_by, new_size; |
46 | 53 | ||
47 | if (btf->types_size == BTF_MAX_NR_TYPES) | 54 | if (btf->types_size == BTF_MAX_NR_TYPES) |
48 | return -E2BIG; | 55 | return -E2BIG; |
@@ -69,7 +76,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t) | |||
69 | static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) | 76 | static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) |
70 | { | 77 | { |
71 | const struct btf_header *hdr = btf->hdr; | 78 | const struct btf_header *hdr = btf->hdr; |
72 | u32 meta_left; | 79 | __u32 meta_left; |
73 | 80 | ||
74 | if (btf->data_size < sizeof(struct btf_header)) { | 81 | if (btf->data_size < sizeof(struct btf_header)) { |
75 | elog("BTF header not found\n"); | 82 | elog("BTF header not found\n"); |
@@ -148,7 +155,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) | |||
148 | 155 | ||
149 | while (next_type < end_type) { | 156 | while (next_type < end_type) { |
150 | struct btf_type *t = next_type; | 157 | struct btf_type *t = next_type; |
151 | uint16_t vlen = BTF_INFO_VLEN(t->info); | 158 | __u16 vlen = BTF_INFO_VLEN(t->info); |
152 | int err; | 159 | int err; |
153 | 160 | ||
154 | next_type += sizeof(*t); | 161 | next_type += sizeof(*t); |
@@ -187,6 +194,14 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) | |||
187 | return 0; | 194 | return 0; |
188 | } | 195 | } |
189 | 196 | ||
197 | const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id) | ||
198 | { | ||
199 | if (type_id > btf->nr_types) | ||
200 | return NULL; | ||
201 | |||
202 | return btf->types[type_id]; | ||
203 | } | ||
204 | |||
190 | static bool btf_type_is_void(const struct btf_type *t) | 205 | static bool btf_type_is_void(const struct btf_type *t) |
191 | { | 206 | { |
192 | return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD; | 207 | return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD; |
@@ -197,7 +212,7 @@ static bool btf_type_is_void_or_null(const struct btf_type *t) | |||
197 | return !t || btf_type_is_void(t); | 212 | return !t || btf_type_is_void(t); |
198 | } | 213 | } |
199 | 214 | ||
200 | static int64_t btf_type_size(const struct btf_type *t) | 215 | static __s64 btf_type_size(const struct btf_type *t) |
201 | { | 216 | { |
202 | switch (BTF_INFO_KIND(t->info)) { | 217 | switch (BTF_INFO_KIND(t->info)) { |
203 | case BTF_KIND_INT: | 218 | case BTF_KIND_INT: |
@@ -214,12 +229,12 @@ static int64_t btf_type_size(const struct btf_type *t) | |||
214 | 229 | ||
215 | #define MAX_RESOLVE_DEPTH 32 | 230 | #define MAX_RESOLVE_DEPTH 32 |
216 | 231 | ||
217 | int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | 232 | __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) |
218 | { | 233 | { |
219 | const struct btf_array *array; | 234 | const struct btf_array *array; |
220 | const struct btf_type *t; | 235 | const struct btf_type *t; |
221 | uint32_t nelems = 1; | 236 | __u32 nelems = 1; |
222 | int64_t size = -1; | 237 | __s64 size = -1; |
223 | int i; | 238 | int i; |
224 | 239 | ||
225 | t = btf__type_by_id(btf, type_id); | 240 | t = btf__type_by_id(btf, type_id); |
@@ -279,9 +294,9 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id) | |||
279 | return type_id; | 294 | return type_id; |
280 | } | 295 | } |
281 | 296 | ||
282 | int32_t btf__find_by_name(const struct btf *btf, const char *type_name) | 297 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name) |
283 | { | 298 | { |
284 | uint32_t i; | 299 | __u32 i; |
285 | 300 | ||
286 | if (!strcmp(type_name, "void")) | 301 | if (!strcmp(type_name, "void")) |
287 | return 0; | 302 | return 0; |
@@ -310,10 +325,9 @@ void btf__free(struct btf *btf) | |||
310 | free(btf); | 325 | free(btf); |
311 | } | 326 | } |
312 | 327 | ||
313 | struct btf *btf__new(uint8_t *data, uint32_t size, | 328 | struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log) |
314 | btf_print_fn_t err_log) | ||
315 | { | 329 | { |
316 | uint32_t log_buf_size = 0; | 330 | __u32 log_buf_size = 0; |
317 | char *log_buf = NULL; | 331 | char *log_buf = NULL; |
318 | struct btf *btf; | 332 | struct btf *btf; |
319 | int err; | 333 | int err; |
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 24f361d99a5e..dd8a86eab8ca 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h | |||
@@ -4,19 +4,21 @@ | |||
4 | #ifndef __BPF_BTF_H | 4 | #ifndef __BPF_BTF_H |
5 | #define __BPF_BTF_H | 5 | #define __BPF_BTF_H |
6 | 6 | ||
7 | #include <stdint.h> | 7 | #include <linux/types.h> |
8 | 8 | ||
9 | #define BTF_ELF_SEC ".BTF" | 9 | #define BTF_ELF_SEC ".BTF" |
10 | 10 | ||
11 | struct btf; | 11 | struct btf; |
12 | struct btf_type; | ||
12 | 13 | ||
13 | typedef int (*btf_print_fn_t)(const char *, ...) | 14 | typedef int (*btf_print_fn_t)(const char *, ...) |
14 | __attribute__((format(printf, 1, 2))); | 15 | __attribute__((format(printf, 1, 2))); |
15 | 16 | ||
16 | void btf__free(struct btf *btf); | 17 | void btf__free(struct btf *btf); |
17 | struct btf *btf__new(uint8_t *data, uint32_t size, btf_print_fn_t err_log); | 18 | struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); |
18 | int32_t btf__find_by_name(const struct btf *btf, const char *type_name); | 19 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name); |
19 | int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id); | 20 | const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); |
21 | __s64 btf__resolve_size(const struct btf *btf, __u32 type_id); | ||
20 | int btf__resolve_type(const struct btf *btf, __u32 type_id); | 22 | int btf__resolve_type(const struct btf *btf, __u32 type_id); |
21 | int btf__fd(const struct btf *btf); | 23 | int btf__fd(const struct btf *btf); |
22 | const char *btf__name_by_offset(const struct btf *btf, __u32 offset); | 24 | const char *btf__name_by_offset(const struct btf *btf, __u32 offset); |
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 | ||
970 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) | 971 | static 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 | ||
2144 | uint32_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 | ||
2149 | uint32_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) |
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 1f8fc2060460..413778a93499 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h | |||
@@ -254,8 +254,8 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj); | |||
254 | int bpf_map__fd(struct bpf_map *map); | 254 | int bpf_map__fd(struct bpf_map *map); |
255 | const struct bpf_map_def *bpf_map__def(struct bpf_map *map); | 255 | const struct bpf_map_def *bpf_map__def(struct bpf_map *map); |
256 | const char *bpf_map__name(struct bpf_map *map); | 256 | const char *bpf_map__name(struct bpf_map *map); |
257 | uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map); | 257 | __u32 bpf_map__btf_key_type_id(const struct bpf_map *map); |
258 | uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map); | 258 | __u32 bpf_map__btf_value_type_id(const struct bpf_map *map); |
259 | 259 | ||
260 | typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); | 260 | typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); |
261 | int bpf_map__set_priv(struct bpf_map *map, void *priv, | 261 | int bpf_map__set_priv(struct bpf_map *map, void *priv, |