Commit c975d94a authored by Daniel Borkmann's avatar Daniel Borkmann

Merge branch 'bpf-drop-libbpf-from-preload'

Alexei Starovoitov says:

====================
CO-RE in the kernel support allows bpf preload to switch to light
skeleton and remove libbpf dependency.

This reduces the size of bpf_preload_umd from 300kbyte to 19kbyte
and eventually will make "kernel skeleton" possible.
====================
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parents 533de4ae e96f2d64
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
LIBBPF_SRCS = $(srctree)/tools/lib/bpf/ LIBBPF_SRCS = $(srctree)/tools/lib/bpf/
LIBBPF_OUT = $(abspath $(obj))/libbpf LIBBPF_INCLUDE = $(LIBBPF_SRCS)/..
LIBBPF_A = $(LIBBPF_OUT)/libbpf.a
LIBBPF_DESTDIR = $(LIBBPF_OUT)
LIBBPF_INCLUDE = $(LIBBPF_DESTDIR)/include
# Although not in use by libbpf's Makefile, set $(O) so that the "dummy" test
# in tools/scripts/Makefile.include always succeeds when building the kernel
# with $(O) pointing to a relative path, as in "make O=build bindeb-pkg".
$(LIBBPF_A): | $(LIBBPF_OUT)
$(Q)$(MAKE) -C $(LIBBPF_SRCS) O=$(LIBBPF_OUT)/ OUTPUT=$(LIBBPF_OUT)/ \
DESTDIR=$(LIBBPF_DESTDIR) prefix= \
$(LIBBPF_OUT)/libbpf.a install_headers
libbpf_hdrs: $(LIBBPF_A)
.PHONY: libbpf_hdrs
$(LIBBPF_OUT):
$(call msg,MKDIR,$@)
$(Q)mkdir -p $@
userccflags += -I $(srctree)/tools/include/ -I $(srctree)/tools/include/uapi \ userccflags += -I $(srctree)/tools/include/ -I $(srctree)/tools/include/uapi \
-I $(LIBBPF_INCLUDE) -Wno-unused-result -I $(LIBBPF_INCLUDE) -Wno-unused-result
userprogs := bpf_preload_umd userprogs := bpf_preload_umd
clean-files := libbpf/
$(obj)/iterators/iterators.o: | libbpf_hdrs
bpf_preload_umd-objs := iterators/iterators.o bpf_preload_umd-objs := iterators/iterators.o
bpf_preload_umd-userldlibs := $(LIBBPF_A) -lelf -lz
$(obj)/bpf_preload_umd: $(LIBBPF_A) $(obj)/bpf_preload_umd:
$(obj)/bpf_preload_umd_blob.o: $(obj)/bpf_preload_umd $(obj)/bpf_preload_umd_blob.o: $(obj)/bpf_preload_umd
......
...@@ -35,15 +35,15 @@ endif ...@@ -35,15 +35,15 @@ endif
.PHONY: all clean .PHONY: all clean
all: iterators.skel.h all: iterators.lskel.h
clean: clean:
$(call msg,CLEAN) $(call msg,CLEAN)
$(Q)rm -rf $(OUTPUT) iterators $(Q)rm -rf $(OUTPUT) iterators
iterators.skel.h: $(OUTPUT)/iterators.bpf.o | $(BPFTOOL) iterators.lskel.h: $(OUTPUT)/iterators.bpf.o | $(BPFTOOL)
$(call msg,GEN-SKEL,$@) $(call msg,GEN-SKEL,$@)
$(Q)$(BPFTOOL) gen skeleton $< > $@ $(Q)$(BPFTOOL) gen skeleton -L $< > $@
$(OUTPUT)/iterators.bpf.o: iterators.bpf.c $(BPFOBJ) | $(OUTPUT) $(OUTPUT)/iterators.bpf.o: iterators.bpf.c $(BPFOBJ) | $(OUTPUT)
......
...@@ -10,20 +10,36 @@ ...@@ -10,20 +10,36 @@
#include <bpf/libbpf.h> #include <bpf/libbpf.h>
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include <sys/mount.h> #include <sys/mount.h>
#include "iterators.skel.h" #include "iterators.lskel.h"
#include "bpf_preload_common.h" #include "bpf_preload_common.h"
int to_kernel = -1; int to_kernel = -1;
int from_kernel = 0; int from_kernel = 0;
static int send_link_to_kernel(struct bpf_link *link, const char *link_name) static int __bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len)
{
union bpf_attr attr;
int err;
memset(&attr, 0, sizeof(attr));
attr.info.bpf_fd = bpf_fd;
attr.info.info_len = *info_len;
attr.info.info = (long) info;
err = skel_sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
if (!err)
*info_len = attr.info.info_len;
return err;
}
static int send_link_to_kernel(int link_fd, const char *link_name)
{ {
struct bpf_preload_info obj = {}; struct bpf_preload_info obj = {};
struct bpf_link_info info = {}; struct bpf_link_info info = {};
__u32 info_len = sizeof(info); __u32 info_len = sizeof(info);
int err; int err;
err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &info, &info_len); err = __bpf_obj_get_info_by_fd(link_fd, &info, &info_len);
if (err) if (err)
return err; return err;
obj.link_id = info.id; obj.link_id = info.id;
...@@ -37,7 +53,6 @@ static int send_link_to_kernel(struct bpf_link *link, const char *link_name) ...@@ -37,7 +53,6 @@ static int send_link_to_kernel(struct bpf_link *link, const char *link_name)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
struct iterators_bpf *skel; struct iterators_bpf *skel;
int err, magic; int err, magic;
int debug_fd; int debug_fd;
...@@ -55,7 +70,6 @@ int main(int argc, char **argv) ...@@ -55,7 +70,6 @@ int main(int argc, char **argv)
printf("bad start magic %d\n", magic); printf("bad start magic %d\n", magic);
return 1; return 1;
} }
setrlimit(RLIMIT_MEMLOCK, &rlim);
/* libbpf opens BPF object and loads it into the kernel */ /* libbpf opens BPF object and loads it into the kernel */
skel = iterators_bpf__open_and_load(); skel = iterators_bpf__open_and_load();
if (!skel) { if (!skel) {
...@@ -72,10 +86,10 @@ int main(int argc, char **argv) ...@@ -72,10 +86,10 @@ int main(int argc, char **argv)
goto cleanup; goto cleanup;
/* send two bpf_link IDs with names to the kernel */ /* send two bpf_link IDs with names to the kernel */
err = send_link_to_kernel(skel->links.dump_bpf_map, "maps.debug"); err = send_link_to_kernel(skel->links.dump_bpf_map_fd, "maps.debug");
if (err) if (err)
goto cleanup; goto cleanup;
err = send_link_to_kernel(skel->links.dump_bpf_prog, "progs.debug"); err = send_link_to_kernel(skel->links.dump_bpf_prog_fd, "progs.debug");
if (err) if (err)
goto cleanup; goto cleanup;
......
This diff is collapsed.
This diff is collapsed.
...@@ -381,10 +381,13 @@ static void codegen_attach_detach(struct bpf_object *obj, const char *obj_name) ...@@ -381,10 +381,13 @@ static void codegen_attach_detach(struct bpf_object *obj, const char *obj_name)
switch (bpf_program__type(prog)) { switch (bpf_program__type(prog)) {
case BPF_PROG_TYPE_RAW_TRACEPOINT: case BPF_PROG_TYPE_RAW_TRACEPOINT:
tp_name = strchr(bpf_program__section_name(prog), '/') + 1; tp_name = strchr(bpf_program__section_name(prog), '/') + 1;
printf("\tint fd = bpf_raw_tracepoint_open(\"%s\", prog_fd);\n", tp_name); printf("\tint fd = skel_raw_tracepoint_open(\"%s\", prog_fd);\n", tp_name);
break; break;
case BPF_PROG_TYPE_TRACING: case BPF_PROG_TYPE_TRACING:
printf("\tint fd = bpf_raw_tracepoint_open(NULL, prog_fd);\n"); if (bpf_program__expected_attach_type(prog) == BPF_TRACE_ITER)
printf("\tint fd = skel_link_create(prog_fd, 0, BPF_TRACE_ITER);\n");
else
printf("\tint fd = skel_raw_tracepoint_open(NULL, prog_fd);\n");
break; break;
default: default:
printf("\tint fd = ((void)prog_fd, 0); /* auto-attach not supported */\n"); printf("\tint fd = ((void)prog_fd, 0); /* auto-attach not supported */\n");
......
...@@ -70,19 +70,85 @@ static inline int skel_closenz(int fd) ...@@ -70,19 +70,85 @@ static inline int skel_closenz(int fd)
return -EINVAL; return -EINVAL;
} }
#ifndef offsetofend
#define offsetofend(TYPE, MEMBER) \
(offsetof(TYPE, MEMBER) + sizeof((((TYPE *)0)->MEMBER)))
#endif
static inline int skel_map_create(enum bpf_map_type map_type,
const char *map_name,
__u32 key_size,
__u32 value_size,
__u32 max_entries)
{
const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
union bpf_attr attr;
memset(&attr, 0, attr_sz);
attr.map_type = map_type;
strncpy(attr.map_name, map_name, sizeof(attr.map_name));
attr.key_size = key_size;
attr.value_size = value_size;
attr.max_entries = max_entries;
return skel_sys_bpf(BPF_MAP_CREATE, &attr, attr_sz);
}
static inline int skel_map_update_elem(int fd, const void *key,
const void *value, __u64 flags)
{
const size_t attr_sz = offsetofend(union bpf_attr, flags);
union bpf_attr attr;
memset(&attr, 0, attr_sz);
attr.map_fd = fd;
attr.key = (long) key;
attr.value = (long) value;
attr.flags = flags;
return skel_sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, attr_sz);
}
static inline int skel_raw_tracepoint_open(const char *name, int prog_fd)
{
const size_t attr_sz = offsetofend(union bpf_attr, raw_tracepoint.prog_fd);
union bpf_attr attr;
memset(&attr, 0, attr_sz);
attr.raw_tracepoint.name = (long) name;
attr.raw_tracepoint.prog_fd = prog_fd;
return skel_sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, attr_sz);
}
static inline int skel_link_create(int prog_fd, int target_fd,
enum bpf_attach_type attach_type)
{
const size_t attr_sz = offsetofend(union bpf_attr, link_create.iter_info_len);
union bpf_attr attr;
memset(&attr, 0, attr_sz);
attr.link_create.prog_fd = prog_fd;
attr.link_create.target_fd = target_fd;
attr.link_create.attach_type = attach_type;
return skel_sys_bpf(BPF_LINK_CREATE, &attr, attr_sz);
}
static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts) static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
{ {
int map_fd = -1, prog_fd = -1, key = 0, err; int map_fd = -1, prog_fd = -1, key = 0, err;
union bpf_attr attr; union bpf_attr attr;
map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "__loader.map", 4, opts->data_sz, 1, NULL); map_fd = skel_map_create(BPF_MAP_TYPE_ARRAY, "__loader.map", 4, opts->data_sz, 1);
if (map_fd < 0) { if (map_fd < 0) {
opts->errstr = "failed to create loader map"; opts->errstr = "failed to create loader map";
err = -errno; err = -errno;
goto out; goto out;
} }
err = bpf_map_update_elem(map_fd, &key, opts->data, 0); err = skel_map_update_elem(map_fd, &key, opts->data, 0);
if (err < 0) { if (err < 0) {
opts->errstr = "failed to update loader map"; opts->errstr = "failed to update loader map";
err = -errno; err = -errno;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment