Commit a352a824 authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'libbpf-extern-followups'

Andrii Nakryiko says:

====================
Based on latest feedback and discussions, this patch set implements the
following changes:

- Kconfig-provided externs have to be in .kconfig section, for which
  bpf_helpers.h provides convenient __kconfig macro (Daniel);
- instead of allowing to override Kconfig file path, switch this to ability to
  extend and override system Kconfig with user-provided custom values (Alexei);
- BTF is required when externs are used.
====================
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents d6958706 630628cb
...@@ -83,8 +83,8 @@ static const char *get_map_ident(const struct bpf_map *map) ...@@ -83,8 +83,8 @@ static const char *get_map_ident(const struct bpf_map *map)
return "rodata"; return "rodata";
else if (str_has_suffix(name, ".bss")) else if (str_has_suffix(name, ".bss"))
return "bss"; return "bss";
else if (str_has_suffix(name, ".extern")) else if (str_has_suffix(name, ".kconfig"))
return "externs"; /* extern is a C keyword */ return "kconfig";
else else
return NULL; return NULL;
} }
...@@ -112,8 +112,8 @@ static int codegen_datasec_def(struct bpf_object *obj, ...@@ -112,8 +112,8 @@ static int codegen_datasec_def(struct bpf_object *obj,
sec_ident = "bss"; sec_ident = "bss";
else if (strcmp(sec_name, ".rodata") == 0) else if (strcmp(sec_name, ".rodata") == 0)
sec_ident = "rodata"; sec_ident = "rodata";
else if (strcmp(sec_name, ".extern") == 0) else if (strcmp(sec_name, ".kconfig") == 0)
sec_ident = "externs"; /* extern is a C keyword */ sec_ident = "kconfig";
else else
return 0; return 0;
......
...@@ -53,4 +53,6 @@ enum libbpf_tristate { ...@@ -53,4 +53,6 @@ enum libbpf_tristate {
TRI_MODULE = 2, TRI_MODULE = 2,
}; };
#define __kconfig __attribute__((section(".kconfig")))
#endif #endif
This diff is collapsed.
...@@ -85,12 +85,12 @@ struct bpf_object_open_opts { ...@@ -85,12 +85,12 @@ struct bpf_object_open_opts {
*/ */
const char *pin_root_path; const char *pin_root_path;
__u32 attach_prog_fd; __u32 attach_prog_fd;
/* kernel config file path override (for CONFIG_ externs); can point /* Additional kernel config content that augments and overrides
* to either uncompressed text file or .gz file * system Kconfig for CONFIG_xxx externs.
*/ */
const char *kconfig_path; const char *kconfig;
}; };
#define bpf_object_open_opts__last_field kconfig_path #define bpf_object_open_opts__last_field kconfig
LIBBPF_API struct bpf_object *bpf_object__open(const char *path); LIBBPF_API struct bpf_object *bpf_object__open(const char *path);
LIBBPF_API struct bpf_object * LIBBPF_API struct bpf_object *
......
...@@ -23,19 +23,13 @@ static uint32_t get_kernel_version(void) ...@@ -23,19 +23,13 @@ static uint32_t get_kernel_version(void)
static struct test_case { static struct test_case {
const char *name; const char *name;
const char *cfg; const char *cfg;
const char *cfg_path;
bool fails; bool fails;
struct test_core_extern__data data; struct test_core_extern__data data;
} test_cases[] = { } test_cases[] = {
{ .name = "default search path", .cfg_path = NULL, { .name = "default search path", .data = { .bpf_syscall = true } },
.data = { .bpf_syscall = true } },
{ .name = "/proc/config.gz", .cfg_path = "/proc/config.gz",
.data = { .bpf_syscall = true } },
{ .name = "missing config", .fails = true,
.cfg_path = "/proc/invalid-config.gz" },
{ {
.name = "custom values", .name = "custom values",
.cfg = "CONFIG_BPF_SYSCALL=y\n" .cfg = "CONFIG_BPF_SYSCALL=n\n"
"CONFIG_TRISTATE=m\n" "CONFIG_TRISTATE=m\n"
"CONFIG_BOOL=y\n" "CONFIG_BOOL=y\n"
"CONFIG_CHAR=100\n" "CONFIG_CHAR=100\n"
...@@ -45,7 +39,7 @@ static struct test_case { ...@@ -45,7 +39,7 @@ static struct test_case {
"CONFIG_STR=\"abracad\"\n" "CONFIG_STR=\"abracad\"\n"
"CONFIG_MISSING=0", "CONFIG_MISSING=0",
.data = { .data = {
.bpf_syscall = true, .bpf_syscall = false,
.tristate_val = TRI_MODULE, .tristate_val = TRI_MODULE,
.bool_val = true, .bool_val = true,
.char_val = 100, .char_val = 100,
...@@ -133,30 +127,14 @@ void test_core_extern(void) ...@@ -133,30 +127,14 @@ void test_core_extern(void)
int n = sizeof(*skel->data) / sizeof(uint64_t); int n = sizeof(*skel->data) / sizeof(uint64_t);
for (i = 0; i < ARRAY_SIZE(test_cases); i++) { for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
char tmp_cfg_path[] = "/tmp/test_core_extern_cfg.XXXXXX";
struct test_case *t = &test_cases[i]; struct test_case *t = &test_cases[i];
DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
.kconfig_path = t->cfg_path, .kconfig = t->cfg,
); );
if (!test__start_subtest(t->name)) if (!test__start_subtest(t->name))
continue; continue;
if (t->cfg) {
size_t n = strlen(t->cfg) + 1;
int fd = mkstemp(tmp_cfg_path);
int written;
if (CHECK(fd < 0, "mkstemp", "errno: %d\n", errno))
continue;
printf("using '%s' as config file\n", tmp_cfg_path);
written = write(fd, t->cfg, n);
close(fd);
if (CHECK_FAIL(written != n))
goto cleanup;
opts.kconfig_path = tmp_cfg_path;
}
skel = test_core_extern__open_opts(&opts); skel = test_core_extern__open_opts(&opts);
if (CHECK(!skel, "skel_open", "skeleton open failed\n")) if (CHECK(!skel, "skel_open", "skeleton open failed\n"))
goto cleanup; goto cleanup;
...@@ -185,8 +163,6 @@ void test_core_extern(void) ...@@ -185,8 +163,6 @@ void test_core_extern(void)
j, exp[j], got[j]); j, exp[j], got[j]);
} }
cleanup: cleanup:
if (t->cfg)
unlink(tmp_cfg_path);
test_core_extern__destroy(skel); test_core_extern__destroy(skel);
skel = NULL; skel = NULL;
} }
......
...@@ -15,20 +15,18 @@ void test_skeleton(void) ...@@ -15,20 +15,18 @@ void test_skeleton(void)
int duration = 0, err; int duration = 0, err;
struct test_skeleton* skel; struct test_skeleton* skel;
struct test_skeleton__bss *bss; struct test_skeleton__bss *bss;
struct test_skeleton__externs *exts; struct test_skeleton__kconfig *kcfg;
skel = test_skeleton__open(); skel = test_skeleton__open();
if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
return; return;
printf("EXTERNS BEFORE: %p\n", skel->externs); if (CHECK(skel->kconfig, "skel_kconfig", "kconfig is mmaped()!\n"))
if (CHECK(skel->externs, "skel_externs", "externs are mmaped()!\n"))
goto cleanup; goto cleanup;
err = test_skeleton__load(skel); err = test_skeleton__load(skel);
if (CHECK(err, "skel_load", "failed to load skeleton: %d\n", err)) if (CHECK(err, "skel_load", "failed to load skeleton: %d\n", err))
goto cleanup; goto cleanup;
printf("EXTERNS AFTER: %p\n", skel->externs);
bss = skel->bss; bss = skel->bss;
bss->in1 = 1; bss->in1 = 1;
...@@ -37,7 +35,7 @@ void test_skeleton(void) ...@@ -37,7 +35,7 @@ void test_skeleton(void)
bss->in4 = 4; bss->in4 = 4;
bss->in5.a = 5; bss->in5.a = 5;
bss->in5.b = 6; bss->in5.b = 6;
exts = skel->externs; kcfg = skel->kconfig;
err = test_skeleton__attach(skel); err = test_skeleton__attach(skel);
if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
...@@ -55,10 +53,10 @@ void test_skeleton(void) ...@@ -55,10 +53,10 @@ void test_skeleton(void)
CHECK(bss->handler_out5.b != 6, "res6", "got %lld != exp %d\n", CHECK(bss->handler_out5.b != 6, "res6", "got %lld != exp %d\n",
bss->handler_out5.b, 6); bss->handler_out5.b, 6);
CHECK(bss->bpf_syscall != exts->CONFIG_BPF_SYSCALL, "ext1", CHECK(bss->bpf_syscall != kcfg->CONFIG_BPF_SYSCALL, "ext1",
"got %d != exp %d\n", bss->bpf_syscall, exts->CONFIG_BPF_SYSCALL); "got %d != exp %d\n", bss->bpf_syscall, kcfg->CONFIG_BPF_SYSCALL);
CHECK(bss->kern_ver != exts->LINUX_KERNEL_VERSION, "ext2", CHECK(bss->kern_ver != kcfg->LINUX_KERNEL_VERSION, "ext2",
"got %d != exp %d\n", bss->kern_ver, exts->LINUX_KERNEL_VERSION); "got %d != exp %d\n", bss->kern_ver, kcfg->LINUX_KERNEL_VERSION);
cleanup: cleanup:
test_skeleton__destroy(skel); test_skeleton__destroy(skel);
......
...@@ -10,16 +10,16 @@ ...@@ -10,16 +10,16 @@
/* non-existing BPF helper, to test dead code elimination */ /* non-existing BPF helper, to test dead code elimination */
static int (*bpf_missing_helper)(const void *arg1, int arg2) = (void *) 999; static int (*bpf_missing_helper)(const void *arg1, int arg2) = (void *) 999;
extern int LINUX_KERNEL_VERSION; extern int LINUX_KERNEL_VERSION __kconfig;
extern bool CONFIG_BPF_SYSCALL; /* strong */ extern bool CONFIG_BPF_SYSCALL __kconfig; /* strong */
extern enum libbpf_tristate CONFIG_TRISTATE __weak; extern enum libbpf_tristate CONFIG_TRISTATE __kconfig __weak;
extern bool CONFIG_BOOL __weak; extern bool CONFIG_BOOL __kconfig __weak;
extern char CONFIG_CHAR __weak; extern char CONFIG_CHAR __kconfig __weak;
extern uint16_t CONFIG_USHORT __weak; extern uint16_t CONFIG_USHORT __kconfig __weak;
extern int CONFIG_INT __weak; extern int CONFIG_INT __kconfig __weak;
extern uint64_t CONFIG_ULONG __weak; extern uint64_t CONFIG_ULONG __kconfig __weak;
extern const char CONFIG_STR[8] __weak; extern const char CONFIG_STR[8] __kconfig __weak;
extern uint64_t CONFIG_MISSING __weak; extern uint64_t CONFIG_MISSING __kconfig __weak;
uint64_t kern_ver = -1; uint64_t kern_ver = -1;
uint64_t bpf_syscall = -1; uint64_t bpf_syscall = -1;
......
...@@ -21,8 +21,8 @@ char out3 = 0; ...@@ -21,8 +21,8 @@ char out3 = 0;
long long out4 = 0; long long out4 = 0;
int out1 = 0; int out1 = 0;
extern bool CONFIG_BPF_SYSCALL; extern bool CONFIG_BPF_SYSCALL __kconfig;
extern int LINUX_KERNEL_VERSION; extern int LINUX_KERNEL_VERSION __kconfig;
bool bpf_syscall = 0; bool bpf_syscall = 0;
int kern_ver = 0; int kern_ver = 0;
......
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