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

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

 





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.


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