Skip to content

Commit

Permalink
bpf-preload: Switch to new preload registration method
Browse files Browse the repository at this point in the history
Modify the automatic generator of the light skeleton by adding three calls
to bpf_preload_set_ops() for registering and unregistering a preload
method, two in load_skel() (set and unset if there is an error) and one in
free_objs_and_skel().

Regenerate the light skeleton of the already preloaded eBPF program
iterators_bpf, which will now use the new registration method, and directly
call load_skel() and free_objs_and_skel() in the init and fini module
entrypoints.

Finally, allow users to specify a customized list of eBPF programs to
preload with the CONFIG_BPF_PRELOAD_LIST option in the kernel
configuration, at build time, or with new kernel option bpf_preload_list=,
at run-time.

By default, set CONFIG_BPF_PRELOAD_LIST to 'bpf_preload', so that the
current preloading behavior is kept unchanged.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
  • Loading branch information
robertosassu authored and intel-lab-lkp committed Mar 28, 2022
1 parent 73f1cb8 commit 2e0e81b
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 33 deletions.
8 changes: 8 additions & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Expand Up @@ -482,6 +482,14 @@
bgrt_disable [ACPI][X86]
Disable BGRT to avoid flickering OEM logo.

bpf_preload_list= [BPF]
Specify a list of eBPF programs to preload.
Format: obj_name1,obj_name2,...
Default: bpf_preload

Specify the list of eBPF programs to preload when the
bpf filesystem is mounted.

bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
bttv.radio= Most important insmod options are available as
kernel args too.
Expand Down
16 changes: 14 additions & 2 deletions kernel/bpf/inode.c
Expand Up @@ -22,7 +22,14 @@
#include <linux/bpf_trace.h>
#include <linux/bpf_preload.h>

static char *bpf_preload_list_str;
static char *bpf_preload_list_str = CONFIG_BPF_PRELOAD_LIST;

static int __init bpf_preload_list_setup(char *str)
{
bpf_preload_list_str = str;
return 1;
}
__setup("bpf_preload_list=", bpf_preload_list_setup);

static void *bpf_any_get(void *raw, enum bpf_type type)
{
Expand Down Expand Up @@ -732,7 +739,12 @@ static bool bpf_preload_list_mod_get(void)
struct bpf_preload_ops_item *cur;
bool ret = false;

ret |= bpf_preload_mod_get("bpf_preload", &bpf_preload_ops);
/*
* Keep the legacy registration method, but do not attempt to load
* bpf_preload.ko, as it switched to the new registration method.
*/
if (bpf_preload_ops)
ret |= bpf_preload_mod_get("bpf_preload", &bpf_preload_ops);

list_for_each_entry(cur, &preload_list, list)
ret |= bpf_preload_mod_get(cur->obj_name, &cur->ops);
Expand Down
25 changes: 18 additions & 7 deletions kernel/bpf/preload/Kconfig
Expand Up @@ -4,23 +4,34 @@ config USERMODE_DRIVER
default n

menuconfig BPF_PRELOAD
bool "Preload BPF file system with kernel specific program and map iterators"
bool "Preload eBPF programs"
depends on BPF
depends on BPF_SYSCALL
# The dependency on !COMPILE_TEST prevents it from being enabled
# in allmodconfig or allyesconfig configurations
depends on !COMPILE_TEST
select USERMODE_DRIVER
help
This builds kernel module with several embedded BPF programs that are
pinned into BPF FS mount point as human readable files that are
useful in debugging and introspection of BPF programs and maps.
This enables preloading eBPF programs chosen from the kernel
configuration or from the kernel option bpf_preload_list=.

if BPF_PRELOAD
config BPF_PRELOAD_UMD
tristate "bpf_preload kernel module"
tristate "Preload BPF file system with kernel specific program and map iterators"
default m
help
This builds bpf_preload kernel module with embedded BPF programs for
introspection in bpffs.
This builds bpf_preload kernel module with several embedded BPF
programs that are pinned into BPF FS mount point as human readable
files that are useful in debugging and introspection of BPF programs
and maps.

config BPF_PRELOAD_LIST
string "Ordered list of eBPF programs to preload"
default "bpf_preload"
help
A comma-separated list of eBPF programs to preload. Any eBPF program
left off this list will be ignored. This can be controlled at boot
with the "bpf_preload_list=" parameter.

If unsure, leave this as the default.
endif
20 changes: 2 additions & 18 deletions kernel/bpf/preload/bpf_preload_kern.c
Expand Up @@ -5,22 +5,6 @@
#include <linux/bpf_preload.h>
#include "iterators/iterators.lskel.h"

static int __init load(void)
{
int err;

err = load_skel();
if (err)
return err;
bpf_preload_ops = &ops;
return err;
}

static void __exit fini(void)
{
bpf_preload_ops = NULL;
free_objs_and_skel();
}
late_initcall(load);
module_exit(fini);
late_initcall(load_skel);
module_exit(free_objs_and_skel);
MODULE_LICENSE("GPL");
9 changes: 7 additions & 2 deletions kernel/bpf/preload/iterators/iterators.lskel.h
Expand Up @@ -440,6 +440,8 @@ static struct iterators_bpf *skel;

static void free_objs_and_skel(void)
{
bpf_preload_set_ops("bpf_preload", THIS_MODULE, NULL);

if (!IS_ERR_OR_NULL(dump_bpf_map_link))
bpf_link_put(dump_bpf_map_link);
if (!IS_ERR_OR_NULL(dump_bpf_prog_link))
Expand Down Expand Up @@ -481,11 +483,14 @@ static struct bpf_preload_ops ops = {

static int load_skel(void)
{
int err;
int err = -ENOMEM;

if (!bpf_preload_set_ops("bpf_preload", THIS_MODULE, &ops))
return 0;

skel = iterators_bpf__open();
if (!skel)
return -ENOMEM;
goto out;

err = iterators_bpf__load(skel);
if (err)
Expand Down
15 changes: 11 additions & 4 deletions tools/bpf/bpftool/gen.c
Expand Up @@ -700,7 +700,10 @@ static void codegen_preload_free(struct bpf_object *obj, const char *obj_name)
\n\
static void free_objs_and_skel(void) \n\
{ \n\
");
bpf_preload_set_ops(\"%s\", THIS_MODULE, NULL); \n\
\n\
", !strcmp(obj_name, "iterators_bpf") ?
"bpf_preload" : obj_name);

bpf_object__for_each_program(prog, obj) {
codegen("\
Expand Down Expand Up @@ -864,11 +867,14 @@ static void codegen_preload_load(struct bpf_object *obj, const char *obj_name)
\n\
static int load_skel(void) \n\
{ \n\
int err; \n\
int err = -ENOMEM; \n\
\n\
if (!bpf_preload_set_ops(\"%2$s\", THIS_MODULE, &ops)) \n\
return 0; \n\
\n\
skel = %1$s__open(); \n\
if (!skel) \n\
return -ENOMEM; \n\
goto out; \n\
\n\
err = %1$s__load(skel); \n\
if (err) \n\
Expand All @@ -877,7 +883,8 @@ static void codegen_preload_load(struct bpf_object *obj, const char *obj_name)
err = %1$s__attach(skel); \n\
if (err) \n\
goto out; \n\
", obj_name);
", obj_name, !strcmp(obj_name, "iterators_bpf") ?
"bpf_preload" : obj_name);

bpf_object__for_each_program(prog, obj) {
codegen("\
Expand Down

0 comments on commit 2e0e81b

Please sign in to comment.