aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/libbpf.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-02-06 19:56:20 -0500
committerDavid S. Miller <davem@davemloft.net>2019-02-06 19:56:20 -0500
commite90b1fd83c94d536375d8b9f4916afd15f4db0ed (patch)
treeba50688cc9a6712575aa861ff37b1db53dc472b8 /tools/lib/bpf/libbpf.c
parent907bea9cb8e9b7c4cb6a8042c164f3c24f141006 (diff)
parentdd9cef43c222df7c0d76d34451808e789952379d (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.c125
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) 57static int __base_pr(enum libbpf_print_level level, const char *format,
57static 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
68static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; 66static libbpf_print_fn_t __libbpf_pr = __base_pr;
69static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
70static __printf(1, 2) libbpf_print_fn_t __pr_debug;
71
72#define __pr(func, fmt, ...) \
73do { \
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__) 68void 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
82void libbpf_set_print(libbpf_print_fn_t warn, 73__printf(2, 3)
83 libbpf_print_fn_t info, 74void 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
1058static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) 1051static 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}