Re: bpf: add support to check kernel features in BPF program

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux