On Thu, Jan 4, 2024 at 2:39 PM <andrii@xxxxxxxxxx> wrote: > > From: Andrii Nakryiko <andrii@xxxxxxxxxx> > > Various tests specify extra testing prog_flags when loading BPF > programs, like BPF_F_TEST_RND_HI32, and more recently also > BPF_F_TEST_REG_INVARIANTS. While BPF_F_TEST_RND_HI32 is old enough to > not cause much problem on older kernels, BPF_F_TEST_REG_INVARIANTS is > very fresh and unconditionally specifying it causes selftests to fail on > even slightly outdated kernels. > > This breaks libbpf CI test against 4.9 and 5.15 kernels, it can break > some local development (done outside of VM), etc. > > To prevent this, and guard against similar problems in the future, do > runtime detection of supported "testing flags", and only provide those > that host kernel recognizes. > > Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx> Acked-by: Song Liu <song@xxxxxxxxxx> With one nit below. [...] > diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c > index d2458c1b1671..e1f797c5c501 100644 > --- a/tools/testing/selftests/bpf/testing_helpers.c > +++ b/tools/testing/selftests/bpf/testing_helpers.c > @@ -251,6 +251,34 @@ __u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info) > } > > int extra_prog_load_log_flags = 0; > +static int prog_test_flags = -1; nit: Move prog_test_flags to inside testing_prog_flags() as it is not used by other functions. > + > +int testing_prog_flags(void) > +{ > + static int prog_flags[] = { BPF_F_TEST_RND_HI32, BPF_F_TEST_REG_INVARIANTS }; > + static struct bpf_insn insns[] = { > + BPF_MOV64_IMM(BPF_REG_0, 0), > + BPF_EXIT_INSN(), > + }; > + int insn_cnt = ARRAY_SIZE(insns), i, fd, flags = 0; > + LIBBPF_OPTS(bpf_prog_load_opts, opts); > + > + if (prog_test_flags >= 0) > + return prog_test_flags; > + > + for (i = 0; i < ARRAY_SIZE(prog_flags); i++) { > + opts.prog_flags = prog_flags[i]; > + fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "flag-test", "GPL", > + insns, insn_cnt, &opts); > + if (fd >= 0) { > + flags |= prog_flags[i]; > + close(fd); > + } > + } > + > + prog_test_flags = flags; > + return prog_test_flags; > +} [...]