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.c148
1 files changed, 135 insertions, 13 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3d35bacf656f..6513e0b08795 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -45,6 +45,7 @@
45 45
46#include "libbpf.h" 46#include "libbpf.h"
47#include "bpf.h" 47#include "bpf.h"
48#include "btf.h"
48 49
49#ifndef EM_BPF 50#ifndef EM_BPF
50#define EM_BPF 247 51#define EM_BPF 247
@@ -212,6 +213,8 @@ struct bpf_map {
212 char *name; 213 char *name;
213 size_t offset; 214 size_t offset;
214 struct bpf_map_def def; 215 struct bpf_map_def def;
216 uint32_t btf_key_id;
217 uint32_t btf_value_id;
215 void *priv; 218 void *priv;
216 bpf_map_clear_priv_t clear_priv; 219 bpf_map_clear_priv_t clear_priv;
217}; 220};
@@ -256,6 +259,8 @@ struct bpf_object {
256 */ 259 */
257 struct list_head list; 260 struct list_head list;
258 261
262 struct btf *btf;
263
259 void *priv; 264 void *priv;
260 bpf_object_clear_priv_t clear_priv; 265 bpf_object_clear_priv_t clear_priv;
261 266
@@ -819,7 +824,15 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
819 data->d_size); 824 data->d_size);
820 else if (strcmp(name, "maps") == 0) 825 else if (strcmp(name, "maps") == 0)
821 obj->efile.maps_shndx = idx; 826 obj->efile.maps_shndx = idx;
822 else if (sh.sh_type == SHT_SYMTAB) { 827 else if (strcmp(name, BTF_ELF_SEC) == 0) {
828 obj->btf = btf__new(data->d_buf, data->d_size,
829 __pr_debug);
830 if (IS_ERR(obj->btf)) {
831 pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
832 BTF_ELF_SEC, PTR_ERR(obj->btf));
833 obj->btf = NULL;
834 }
835 } else if (sh.sh_type == SHT_SYMTAB) {
823 if (obj->efile.symbols) { 836 if (obj->efile.symbols) {
824 pr_warning("bpf: multiple SYMTAB in %s\n", 837 pr_warning("bpf: multiple SYMTAB in %s\n",
825 obj->path); 838 obj->path);
@@ -996,33 +1009,126 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
996 return 0; 1009 return 0;
997} 1010}
998 1011
1012static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
1013{
1014 struct bpf_map_def *def = &map->def;
1015 const size_t max_name = 256;
1016 int64_t key_size, value_size;
1017 int32_t key_id, value_id;
1018 char name[max_name];
1019
1020 /* Find key type by name from BTF */
1021 if (snprintf(name, max_name, "%s_key", map->name) == max_name) {
1022 pr_warning("map:%s length of BTF key_type:%s_key is too long\n",
1023 map->name, map->name);
1024 return -EINVAL;
1025 }
1026
1027 key_id = btf__find_by_name(btf, name);
1028 if (key_id < 0) {
1029 pr_debug("map:%s key_type:%s cannot be found in BTF\n",
1030 map->name, name);
1031 return key_id;
1032 }
1033
1034 key_size = btf__resolve_size(btf, key_id);
1035 if (key_size < 0) {
1036 pr_warning("map:%s key_type:%s cannot get the BTF type_size\n",
1037 map->name, name);
1038 return key_size;
1039 }
1040
1041 if (def->key_size != key_size) {
1042 pr_warning("map:%s key_type:%s has BTF type_size:%ld != key_size:%u\n",
1043 map->name, name, key_size, def->key_size);
1044 return -EINVAL;
1045 }
1046
1047 /* Find value type from BTF */
1048 if (snprintf(name, max_name, "%s_value", map->name) == max_name) {
1049 pr_warning("map:%s length of BTF value_type:%s_value is too long\n",
1050 map->name, map->name);
1051 return -EINVAL;
1052 }
1053
1054 value_id = btf__find_by_name(btf, name);
1055 if (value_id < 0) {
1056 pr_debug("map:%s value_type:%s cannot be found in BTF\n",
1057 map->name, name);
1058 return value_id;
1059 }
1060
1061 value_size = btf__resolve_size(btf, value_id);
1062 if (value_size < 0) {
1063 pr_warning("map:%s value_type:%s cannot get the BTF type_size\n",
1064 map->name, name);
1065 return value_size;
1066 }
1067
1068 if (def->value_size != value_size) {
1069 pr_warning("map:%s value_type:%s has BTF type_size:%ld != value_size:%u\n",
1070 map->name, name, value_size, def->value_size);
1071 return -EINVAL;
1072 }
1073
1074 map->btf_key_id = key_id;
1075 map->btf_value_id = value_id;
1076
1077 return 0;
1078}
1079
999static int 1080static int
1000bpf_object__create_maps(struct bpf_object *obj) 1081bpf_object__create_maps(struct bpf_object *obj)
1001{ 1082{
1083 struct bpf_create_map_attr create_attr = {};
1002 unsigned int i; 1084 unsigned int i;
1085 int err;
1003 1086
1004 for (i = 0; i < obj->nr_maps; i++) { 1087 for (i = 0; i < obj->nr_maps; i++) {
1005 struct bpf_map_def *def = &obj->maps[i].def; 1088 struct bpf_map *map = &obj->maps[i];
1006 int *pfd = &obj->maps[i].fd; 1089 struct bpf_map_def *def = &map->def;
1007 1090 int *pfd = &map->fd;
1008 *pfd = bpf_create_map_name(def->type, 1091
1009 obj->maps[i].name, 1092 create_attr.name = map->name;
1010 def->key_size, 1093 create_attr.map_type = def->type;
1011 def->value_size, 1094 create_attr.map_flags = def->map_flags;
1012 def->max_entries, 1095 create_attr.key_size = def->key_size;
1013 def->map_flags); 1096 create_attr.value_size = def->value_size;
1097 create_attr.max_entries = def->max_entries;
1098 create_attr.btf_fd = 0;
1099 create_attr.btf_key_id = 0;
1100 create_attr.btf_value_id = 0;
1101
1102 if (obj->btf && !bpf_map_find_btf_info(map, obj->btf)) {
1103 create_attr.btf_fd = btf__fd(obj->btf);
1104 create_attr.btf_key_id = map->btf_key_id;
1105 create_attr.btf_value_id = map->btf_value_id;
1106 }
1107
1108 *pfd = bpf_create_map_xattr(&create_attr);
1109 if (*pfd < 0 && create_attr.btf_key_id) {
1110 pr_warning("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n",
1111 map->name, strerror(errno), errno);
1112 create_attr.btf_fd = 0;
1113 create_attr.btf_key_id = 0;
1114 create_attr.btf_value_id = 0;
1115 map->btf_key_id = 0;
1116 map->btf_value_id = 0;
1117 *pfd = bpf_create_map_xattr(&create_attr);
1118 }
1119
1014 if (*pfd < 0) { 1120 if (*pfd < 0) {
1015 size_t j; 1121 size_t j;
1016 int err = *pfd;
1017 1122
1123 err = *pfd;
1018 pr_warning("failed to create map (name: '%s'): %s\n", 1124 pr_warning("failed to create map (name: '%s'): %s\n",
1019 obj->maps[i].name, 1125 map->name,
1020 strerror(errno)); 1126 strerror(errno));
1021 for (j = 0; j < i; j++) 1127 for (j = 0; j < i; j++)
1022 zclose(obj->maps[j].fd); 1128 zclose(obj->maps[j].fd);
1023 return err; 1129 return err;
1024 } 1130 }
1025 pr_debug("create map %s: fd=%d\n", obj->maps[i].name, *pfd); 1131 pr_debug("create map %s: fd=%d\n", map->name, *pfd);
1026 } 1132 }
1027 1133
1028 return 0; 1134 return 0;
@@ -1641,6 +1747,7 @@ void bpf_object__close(struct bpf_object *obj)
1641 1747
1642 bpf_object__elf_finish(obj); 1748 bpf_object__elf_finish(obj);
1643 bpf_object__unload(obj); 1749 bpf_object__unload(obj);
1750 btf__free(obj->btf);
1644 1751
1645 for (i = 0; i < obj->nr_maps; i++) { 1752 for (i = 0; i < obj->nr_maps; i++) {
1646 zfree(&obj->maps[i].name); 1753 zfree(&obj->maps[i].name);
@@ -1692,6 +1799,11 @@ unsigned int bpf_object__kversion(struct bpf_object *obj)
1692 return obj ? obj->kern_version : 0; 1799 return obj ? obj->kern_version : 0;
1693} 1800}
1694 1801
1802int bpf_object__btf_fd(const struct bpf_object *obj)
1803{
1804 return obj->btf ? btf__fd(obj->btf) : -1;
1805}
1806
1695int bpf_object__set_priv(struct bpf_object *obj, void *priv, 1807int bpf_object__set_priv(struct bpf_object *obj, void *priv,
1696 bpf_object_clear_priv_t clear_priv) 1808 bpf_object_clear_priv_t clear_priv)
1697{ 1809{
@@ -1937,6 +2049,16 @@ const char *bpf_map__name(struct bpf_map *map)
1937 return map ? map->name : NULL; 2049 return map ? map->name : NULL;
1938} 2050}
1939 2051
2052uint32_t bpf_map__btf_key_id(const struct bpf_map *map)
2053{
2054 return map ? map->btf_key_id : 0;
2055}
2056
2057uint32_t bpf_map__btf_value_id(const struct bpf_map *map)
2058{
2059 return map ? map->btf_value_id : 0;
2060}
2061
1940int bpf_map__set_priv(struct bpf_map *map, void *priv, 2062int bpf_map__set_priv(struct bpf_map *map, void *priv,
1941 bpf_map_clear_priv_t clear_priv) 2063 bpf_map_clear_priv_t clear_priv)
1942{ 2064{