On Fri, May 5, 2023 at 12:53 AM Yonghong Song <yhs@xxxxxxxx> wrote: > > > > On 5/4/23 4:09 AM, Menglong Dong wrote: > > Hello, > > > > I find that it's not supported yet to check if the bpf features are > > supported by the target kernel in the BPF program, which makes > > it hard to keep the BPF program compatible with different kernel > > versions. > > > > For example, I want to use the helper bpf_jiffies64(), but I am not > > sure if it is supported by the target, as my program can run in > > kernel 5.4 or kernel 5.10. Therefore, I have to compile two versions > > BPF elf and load one of them according to the current kernel version. > > The part of BPF program can be this: > > > > #ifdef BPF_FEATS_JIFFIES64 > > jiffies = bpf_jiffies64(); > > #else > > jiffies = 0; > > #endif > > > > And I will generate xxx_no_jiffies.skel.h and xxx_jiffies.skel.h > > with -DBPF_FEATS_JIFFIES64 or not. > > > > This method is too silly, as I have to compile 8(2*2*2) versions of > > the BPF program if I am not sure if 3 bpf helpers are supported by the > > target kernel. > > > > Therefore, I think it may be helpful if we can check if the helpers > > are support like this: > > > > if (bpf_core_helper_exist(bpf_jiffies64)) > > jiffies = bpf_jiffies64(); > > else > > jiffies = 0; > > > > And bpf_core_helper_exist() can be defined like this: > > > > #define bpf_core_helper_exist(helper) \ > > __builtin_preserve_helper_info(helper, BPF_HELPER_EXISTS) > > > > Besides, in order to prevent the verifier from checking the helper > > that is not supported, we need to remove the dead code in libbpf. > > As the kernel already has the ability to remove dead and nop insn, > > we can just make the dead insn to nop. > > > > Another option is to make the BPF program support "const value". > > Such const values can be rewrite before load, the dead code can > > be removed. For example: > > > > #define bpf_const_value __attribute__((preserve_const_value)) > > > > bpf_const_value bool is_bpf_jiffies64_supported = 0; > > > > if (is_bpf_jiffies64_supported) > > jiffies = bpf_jiffies64(); > > else > > jiffies = 0; > > > > The 'is_bpf_jiffies64_supported' will be compiled to an imm, and > > can be rewrite and relocated through libbpf by the user. Then, we > > can make the dead insn 'nop'. > > A variant of the second approach should already work. > You can do, > > volatile const is_bpf_jiffies64_supported; > > ... > > if (is_bpf_jiffies64_supported) > jiffies = bpf_jiffies64(); > else > jiffies = 0; > > > After skeleton is openned but before prog load, you can do > a probe into the kernel to find whether the helper is supported > or not, and set is_bpf_jiffies64_supported accordingly. > > After loading the program, is_bpf_jiffies64_supported will be > changed to 0/1, verifier will do dead code elimination properly. > Great, that works! Thanks~ > > > > What do you think? I'm not sure if these methods work and want > > to get some advice before coding. > > > > Thanks! > > Menglong Dong