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

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

 



On Thu, May 4, 2023 at 7:42 PM Menglong Dong <menglong8.dong@xxxxxxxxx> wrote:
>
> 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)

you don't even have to use global variable to detect helper support, you can do:

if (bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_jiffies64))
    jiffies = bpf_jiffies64();
else
    jiffies = 0;

> >      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