On Thu, Oct 01, 2026 at 10:52 PM Jay Wang <[email protected]> wrote: > + err = __sys_bpf(cmd, USER_BPFPTR(uattr), size, > USER_BPFPTR(uattr_common), size_common); > + if (IS_MODULE(CONFIG_DEBUG_INFO_BTF) && err < 0 && > bpf_btf_vmlinux_retry(cmd, misses)) > + err = __sys_bpf(cmd, USER_BPFPTR(uattr), size, > USER_BPFPTR(uattr_common), > + size_common);
Running the command twice when it failed and a global counter moved is not going to fly. Missing BTF is not always an error. With =m and BTF not loaded yet take int prog(struct xdp_md *ctx) with func_info. That is everything libbpf loads. do_check_common() calls btf_prepare_func_args(env, 0). find_canonical_prog_ctx_type() returns NULL, btf_is_prog_ctx_type() returns false, the arg becomes ARG_PTR_TO_MEM and func_info_aux[0].unreliable is set. The prog loads. err == 0. No retry. >From then on freplace of that prog fails with "Cannot replace static functions" and fentry/fexit see its args as scalars, even after BTF is loaded. With =y both work. That is the only reason why "a socket filter does not load it". In v3 such prog loaded BTF. systemd built with BPF_FRAMEWORK loads int sd_bind4(struct bpf_sock_addr *ctx) from manager_setup_cgroup() at every boot. The result of the verification cannot depend on who touched BTF first. bpf-ci is right too. The first run writes into uattr. It's starting to feel that this is dead end. So much complexity to save few Mbyte. pw-bot: cr
