diff options
author | David S. Miller <davem@davemloft.net> | 2019-02-06 19:56:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-02-06 19:56:20 -0500 |
commit | e90b1fd83c94d536375d8b9f4916afd15f4db0ed (patch) | |
tree | ba50688cc9a6712575aa861ff37b1db53dc472b8 /tools/lib/bpf/libbpf.c | |
parent | 907bea9cb8e9b7c4cb6a8042c164f3c24f141006 (diff) | |
parent | dd9cef43c222df7c0d76d34451808e789952379d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says:
====================
pull-request: bpf-next 2019-02-07
The following pull-request contains BPF updates for your *net-next* tree.
The main changes are:
1) Add a riscv64 JIT for BPF, from Björn.
2) Implement BTF deduplication algorithm for libbpf which takes BTF type
information containing duplicate per-compilation unit information and
reduces it to an equivalent set of BTF types with no duplication and
without loss of information, from Andrii.
3) Offloaded and native BPF XDP programs can coexist today, enable also
offloaded and generic ones as well, from Jakub.
4) Expose various BTF related helper functions in libbpf as API which
are in particular helpful for JITed programs, from Yonghong.
5) Fix the recently added JMP32 code emission in s390x JIT, from Heiko.
6) Fix BPF kselftests' tcp_{server,client}.py to be able to run inside
a network namespace, also add a fix for libbpf to get libbpf_print()
working, from Stanislav.
7) Fixes for bpftool documentation, from Prashant.
8) Type cleanup in BPF kselftests' test_maps.c to silence a gcc8 warning,
from Breno.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r-- | tools/lib/bpf/libbpf.c | 125 |
1 files changed, 32 insertions, 93 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 03bc01ca2577..47969aa0faf8 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "bpf.h" | 42 | #include "bpf.h" |
43 | #include "btf.h" | 43 | #include "btf.h" |
44 | #include "str_error.h" | 44 | #include "str_error.h" |
45 | #include "libbpf_util.h" | ||
45 | 46 | ||
46 | #ifndef EM_BPF | 47 | #ifndef EM_BPF |
47 | #define EM_BPF 247 | 48 | #define EM_BPF 247 |
@@ -53,39 +54,33 @@ | |||
53 | 54 | ||
54 | #define __printf(a, b) __attribute__((format(printf, a, b))) | 55 | #define __printf(a, b) __attribute__((format(printf, a, b))) |
55 | 56 | ||
56 | __printf(1, 2) | 57 | static int __base_pr(enum libbpf_print_level level, const char *format, |
57 | static int __base_pr(const char *format, ...) | 58 | va_list args) |
58 | { | 59 | { |
59 | va_list args; | 60 | if (level == LIBBPF_DEBUG) |
60 | int err; | 61 | return 0; |
61 | 62 | ||
62 | va_start(args, format); | 63 | return vfprintf(stderr, format, args); |
63 | err = vfprintf(stderr, format, args); | ||
64 | va_end(args); | ||
65 | return err; | ||
66 | } | 64 | } |
67 | 65 | ||
68 | static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; | 66 | static libbpf_print_fn_t __libbpf_pr = __base_pr; |
69 | static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr; | ||
70 | static __printf(1, 2) libbpf_print_fn_t __pr_debug; | ||
71 | |||
72 | #define __pr(func, fmt, ...) \ | ||
73 | do { \ | ||
74 | if ((func)) \ | ||
75 | (func)("libbpf: " fmt, ##__VA_ARGS__); \ | ||
76 | } while (0) | ||
77 | 67 | ||
78 | #define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__) | 68 | void libbpf_set_print(libbpf_print_fn_t fn) |
79 | #define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__) | 69 | { |
80 | #define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__) | 70 | __libbpf_pr = fn; |
71 | } | ||
81 | 72 | ||
82 | void libbpf_set_print(libbpf_print_fn_t warn, | 73 | __printf(2, 3) |
83 | libbpf_print_fn_t info, | 74 | void libbpf_print(enum libbpf_print_level level, const char *format, ...) |
84 | libbpf_print_fn_t debug) | ||
85 | { | 75 | { |
86 | __pr_warning = warn; | 76 | va_list args; |
87 | __pr_info = info; | 77 | |
88 | __pr_debug = debug; | 78 | if (!__libbpf_pr) |
79 | return; | ||
80 | |||
81 | va_start(args, format); | ||
82 | __libbpf_pr(level, format, args); | ||
83 | va_end(args); | ||
89 | } | 84 | } |
90 | 85 | ||
91 | #define STRERR_BUFSIZE 128 | 86 | #define STRERR_BUFSIZE 128 |
@@ -839,8 +834,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) | |||
839 | else if (strcmp(name, "maps") == 0) | 834 | else if (strcmp(name, "maps") == 0) |
840 | obj->efile.maps_shndx = idx; | 835 | obj->efile.maps_shndx = idx; |
841 | else if (strcmp(name, BTF_ELF_SEC) == 0) { | 836 | else if (strcmp(name, BTF_ELF_SEC) == 0) { |
842 | obj->btf = btf__new(data->d_buf, data->d_size, | 837 | obj->btf = btf__new(data->d_buf, data->d_size); |
843 | __pr_debug); | ||
844 | if (IS_ERR(obj->btf)) { | 838 | if (IS_ERR(obj->btf)) { |
845 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", | 839 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", |
846 | BTF_ELF_SEC, PTR_ERR(obj->btf)); | 840 | BTF_ELF_SEC, PTR_ERR(obj->btf)); |
@@ -915,8 +909,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) | |||
915 | BTF_EXT_ELF_SEC, BTF_ELF_SEC); | 909 | BTF_EXT_ELF_SEC, BTF_ELF_SEC); |
916 | } else { | 910 | } else { |
917 | obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, | 911 | obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, |
918 | btf_ext_data->d_size, | 912 | btf_ext_data->d_size); |
919 | __pr_debug); | ||
920 | if (IS_ERR(obj->btf_ext)) { | 913 | if (IS_ERR(obj->btf_ext)) { |
921 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", | 914 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", |
922 | BTF_EXT_ELF_SEC, | 915 | BTF_EXT_ELF_SEC, |
@@ -1057,72 +1050,18 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, | |||
1057 | 1050 | ||
1058 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) | 1051 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) |
1059 | { | 1052 | { |
1060 | const struct btf_type *container_type; | ||
1061 | const struct btf_member *key, *value; | ||
1062 | struct bpf_map_def *def = &map->def; | 1053 | struct bpf_map_def *def = &map->def; |
1063 | const size_t max_name = 256; | 1054 | __u32 key_type_id, value_type_id; |
1064 | char container_name[max_name]; | 1055 | int ret; |
1065 | __s64 key_size, value_size; | ||
1066 | __s32 container_id; | ||
1067 | |||
1068 | if (snprintf(container_name, max_name, "____btf_map_%s", map->name) == | ||
1069 | max_name) { | ||
1070 | pr_warning("map:%s length of '____btf_map_%s' is too long\n", | ||
1071 | map->name, map->name); | ||
1072 | return -EINVAL; | ||
1073 | } | ||
1074 | |||
1075 | container_id = btf__find_by_name(btf, container_name); | ||
1076 | if (container_id < 0) { | ||
1077 | pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n", | ||
1078 | map->name, container_name); | ||
1079 | return container_id; | ||
1080 | } | ||
1081 | |||
1082 | container_type = btf__type_by_id(btf, container_id); | ||
1083 | if (!container_type) { | ||
1084 | pr_warning("map:%s cannot find BTF type for container_id:%u\n", | ||
1085 | map->name, container_id); | ||
1086 | return -EINVAL; | ||
1087 | } | ||
1088 | |||
1089 | if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT || | ||
1090 | BTF_INFO_VLEN(container_type->info) < 2) { | ||
1091 | pr_warning("map:%s container_name:%s is an invalid container struct\n", | ||
1092 | map->name, container_name); | ||
1093 | return -EINVAL; | ||
1094 | } | ||
1095 | |||
1096 | key = (struct btf_member *)(container_type + 1); | ||
1097 | value = key + 1; | ||
1098 | |||
1099 | key_size = btf__resolve_size(btf, key->type); | ||
1100 | if (key_size < 0) { | ||
1101 | pr_warning("map:%s invalid BTF key_type_size\n", | ||
1102 | map->name); | ||
1103 | return key_size; | ||
1104 | } | ||
1105 | |||
1106 | if (def->key_size != key_size) { | ||
1107 | pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n", | ||
1108 | map->name, (__u32)key_size, def->key_size); | ||
1109 | return -EINVAL; | ||
1110 | } | ||
1111 | |||
1112 | value_size = btf__resolve_size(btf, value->type); | ||
1113 | if (value_size < 0) { | ||
1114 | pr_warning("map:%s invalid BTF value_type_size\n", map->name); | ||
1115 | return value_size; | ||
1116 | } | ||
1117 | 1056 | ||
1118 | if (def->value_size != value_size) { | 1057 | ret = btf__get_map_kv_tids(btf, map->name, def->key_size, |
1119 | pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n", | 1058 | def->value_size, &key_type_id, |
1120 | map->name, (__u32)value_size, def->value_size); | 1059 | &value_type_id); |
1121 | return -EINVAL; | 1060 | if (ret) |
1122 | } | 1061 | return ret; |
1123 | 1062 | ||
1124 | map->btf_key_type_id = key->type; | 1063 | map->btf_key_type_id = key_type_id; |
1125 | map->btf_value_type_id = value->type; | 1064 | map->btf_value_type_id = value_type_id; |
1126 | 1065 | ||
1127 | return 0; | 1066 | return 0; |
1128 | } | 1067 | } |