On Fri, Feb 03, 2023 at 05:23:29PM +0100, Jiri Olsa wrote: > Moving test_progs helpers to testing_helpers object so they can be > used from test_verifier in following changes. > > Also adding missing ifndef header guard to testing_helpers.h header. > > Using stderr instead of env.stderr because un/load_bpf_testmod helpers > will be used outside test_progs. Also at the point of calling them > in test_progs the std files are not hijacked yet and stderr is the > same as env.stderr. Makes sense. Possibly something to clean up at another time but given that we were being inconsistent with env.stdout and env.stderr in load_bpf_testmod() in the first place, this seems totally fine. Acked-by: David Vernet <void@xxxxxxxxxxxxx> Left one question about kern_sync_rcu() below that need not block this patch series, and can be addressed in a follow-up if it's even relevant. > > Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx> > --- > tools/testing/selftests/bpf/test_progs.c | 67 +------------------ > tools/testing/selftests/bpf/test_progs.h | 1 - > tools/testing/selftests/bpf/testing_helpers.c | 63 +++++++++++++++++ > tools/testing/selftests/bpf/testing_helpers.h | 10 +++ > 4 files changed, 75 insertions(+), 66 deletions(-) > > diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c > index 6d5e3022c75f..39ceb6a1bfc6 100644 > --- a/tools/testing/selftests/bpf/test_progs.c > +++ b/tools/testing/selftests/bpf/test_progs.c > @@ -11,7 +11,6 @@ > #include <signal.h> > #include <string.h> > #include <execinfo.h> /* backtrace */ > -#include <linux/membarrier.h> > #include <sys/sysinfo.h> /* get_nprocs */ > #include <netinet/in.h> > #include <sys/select.h> > @@ -616,68 +615,6 @@ int extract_build_id(char *build_id, size_t size) > return -1; > } > > -static int finit_module(int fd, const char *param_values, int flags) > -{ > - return syscall(__NR_finit_module, fd, param_values, flags); > -} > - > -static int delete_module(const char *name, int flags) > -{ > - return syscall(__NR_delete_module, name, flags); > -} > - > -/* > - * Trigger synchronize_rcu() in kernel. > - */ > -int kern_sync_rcu(void) > -{ > - return syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0, 0); > -} > - > -static void unload_bpf_testmod(void) > -{ > - if (kern_sync_rcu()) > - fprintf(env.stderr, "Failed to trigger kernel-side RCU sync!\n"); > - if (delete_module("bpf_testmod", 0)) { > - if (errno == ENOENT) { > - if (verbose()) > - fprintf(stdout, "bpf_testmod.ko is already unloaded.\n"); > - return; > - } > - fprintf(env.stderr, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno); > - return; > - } > - if (verbose()) > - fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n"); > -} > - > -static int load_bpf_testmod(void) > -{ > - int fd; > - > - /* ensure previous instance of the module is unloaded */ > - unload_bpf_testmod(); > - > - if (verbose()) > - fprintf(stdout, "Loading bpf_testmod.ko...\n"); > - > - fd = open("bpf_testmod.ko", O_RDONLY); > - if (fd < 0) { > - fprintf(env.stderr, "Can't find bpf_testmod.ko kernel module: %d\n", -errno); > - return -ENOENT; > - } > - if (finit_module(fd, "", 0)) { > - fprintf(env.stderr, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno); > - close(fd); > - return -EINVAL; > - } > - close(fd); > - > - if (verbose()) > - fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n"); > - return 0; > -} > - > /* extern declarations for test funcs */ > #define DEFINE_TEST(name) \ > extern void test_##name(void) __weak; \ > @@ -1655,7 +1592,7 @@ int main(int argc, char **argv) > env.stderr = stderr; > > env.has_testmod = true; > - if (!env.list_test_names && load_bpf_testmod()) { > + if (!env.list_test_names && load_bpf_testmod(verbose())) { > fprintf(env.stderr, "WARNING! Selftests relying on bpf_testmod.ko will be skipped.\n"); > env.has_testmod = false; > } > @@ -1754,7 +1691,7 @@ int main(int argc, char **argv) > close(env.saved_netns_fd); > out: > if (!env.list_test_names && env.has_testmod) > - unload_bpf_testmod(); > + unload_bpf_testmod(verbose()); > > free_test_selector(&env.test_selector); > free_test_selector(&env.subtest_selector); > diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h > index d5d51ec97ec8..b9dac3c32712 100644 > --- a/tools/testing/selftests/bpf/test_progs.h > +++ b/tools/testing/selftests/bpf/test_progs.h > @@ -390,7 +390,6 @@ int bpf_find_map(const char *test, struct bpf_object *obj, const char *name); > int compare_map_keys(int map1_fd, int map2_fd); > int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); > int extract_build_id(char *build_id, size_t size); > -int kern_sync_rcu(void); > int trigger_module_test_read(int read_sz); > int trigger_module_test_write(int write_sz); > int write_sysctl(const char *sysctl, const char *value); > diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c > index 9695318e8132..3a9e7e8e5b14 100644 > --- a/tools/testing/selftests/bpf/testing_helpers.c > +++ b/tools/testing/selftests/bpf/testing_helpers.c > @@ -8,6 +8,7 @@ > #include <bpf/libbpf.h> > #include "test_progs.h" > #include "testing_helpers.h" > +#include <linux/membarrier.h> > > int parse_num_list(const char *s, bool **num_set, int *num_set_len) > { > @@ -229,3 +230,65 @@ int bpf_test_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, > > return bpf_prog_load(type, NULL, license, insns, insns_cnt, &opts); > } > + > +static int finit_module(int fd, const char *param_values, int flags) > +{ > + return syscall(__NR_finit_module, fd, param_values, flags); > +} > + > +static int delete_module(const char *name, int flags) > +{ > + return syscall(__NR_delete_module, name, flags); > +} > + > +void unload_bpf_testmod(bool verbose) > +{ > + if (kern_sync_rcu()) > + fprintf(stderr, "Failed to trigger kernel-side RCU sync!\n"); I realize there's no behavior change here, but out of curiosity, do you know why we need a synchronize_rcu() here? In general this feels kind of sketchy, and like something we should just put in bpf_testmod_exit() if it's really needed for something in the kernel. > + if (delete_module("bpf_testmod", 0)) { > + if (errno == ENOENT) { > + if (verbose) > + fprintf(stdout, "bpf_testmod.ko is already unloaded.\n"); > + return; > + } > + fprintf(stderr, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno); > + return; > + } > + if (verbose) > + fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n"); > +} > + > +int load_bpf_testmod(bool verbose) > +{ > + int fd; > + > + /* ensure previous instance of the module is unloaded */ > + unload_bpf_testmod(verbose); > + > + if (verbose) > + fprintf(stdout, "Loading bpf_testmod.ko...\n"); > + > + fd = open("bpf_testmod.ko", O_RDONLY); > + if (fd < 0) { > + fprintf(stderr, "Can't find bpf_testmod.ko kernel module: %d\n", -errno); > + return -ENOENT; > + } > + if (finit_module(fd, "", 0)) { > + fprintf(stderr, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno); > + close(fd); > + return -EINVAL; > + } > + close(fd); > + > + if (verbose) > + fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n"); > + return 0; > +} > + > +/* > + * Trigger synchronize_rcu() in kernel. > + */ > +int kern_sync_rcu(void) > +{ > + return syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0, 0); > +} > diff --git a/tools/testing/selftests/bpf/testing_helpers.h b/tools/testing/selftests/bpf/testing_helpers.h > index 6ec00bf79cb5..7356474def27 100644 > --- a/tools/testing/selftests/bpf/testing_helpers.h > +++ b/tools/testing/selftests/bpf/testing_helpers.h > @@ -1,5 +1,9 @@ > /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ > /* Copyright (C) 2020 Facebook, Inc. */ > + > +#ifndef __TESTING_HELPERS_H > +#define __TESTING_HELPERS_H > + > #include <stdbool.h> > #include <bpf/bpf.h> > #include <bpf/libbpf.h> > @@ -20,3 +24,9 @@ struct test_filter_set; > int parse_test_list(const char *s, > struct test_filter_set *test_set, > bool is_glob_pattern); > + > +int load_bpf_testmod(bool verbose); > +void unload_bpf_testmod(bool verbose); > +int kern_sync_rcu(void); > + > +#endif /* __TESTING_HELPERS_H */ > -- > 2.39.1 >