Re: Portability of bpf_tracing.h

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

 



On Wed, 26 May 2021 at 19:34, Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> wrote:
>
> So I did a bit of investigation and gathered struct pt_regs
> definitions from all the "supported" architectures in bpf_tracing.h.
> I'll leave it here for further reference.
>
> static unsigned long bpf_pt_regs_parm1(const void *regs)
> {
>     if (___arch_is_x86)
>         return ((struct pt_regs___x86 *)regs)->di;
>     else if (___arch_is_s390)
>         return ((struct pt_regs___s390 *)regs)->gprs[2];
>     else if (___arch_is_powerpc)
>         return ((struct pt_regs___powerpc *)regs)->gpr[3];
>     else
>         while(1); /* need some better way to force BPF verification failure */
> }
>
> And so on for other architectures and other helpers, you should get
> the idea from the above.

The idea of basing this on unique fields in types is neat, the
downside I see is that we encode the logic in the BPF bitstream. If in
the future struct pt_regs is changed, code breaks and we can't do much
about it. What if instead we replace ___arch_is_x86, etc. with a
.kconfig style constant load? The platform detection logic can then
live in libbpf or cilium/ebpf and can be evolved if needed. Instead of
while(1) we could use an illegal function call, like we do for
poisoned CORE relocations.

>
> As a shameless plug, if you'd like to see some more examples of using
> CO-RE for detecting kernel features, see [0]
>
>   [0] https://nakryiko.com/posts/bpf-tips-printk/
>
> > > Well, obviously I'm not a fan of even more magic #defines. But I think
> > > we can achieve a similar effect with a more "lazy" approach. I.e., if
> > > user tries to use PT_REGS_xxx macros but doesn't specify the platform
> > > -- only then it gets compilation errors. There is stuff in
> > > bpf_tracing.h that doesn't need pt_regs, so we can't just outright do
> > > #error unconditinally. But we can do something like this:
> > >
> > > #else /* !bpf_target_defined */
> > >
> > > #define PT_REGS_PARM1(x) _Pragma("GCC error \"blah blah something
> > > user-facing\"")
> > >
> > > ... and so on for all macros
> > >
> > > #endif
> > >
> > > Thoughts?
> >
> > That would work for me, but it would change the behaviour for current
> > users of the header, no? That's why I added the magic define in the
> > first place.
>
> How so? If someone is using PT_REGS_PARM1 without setting target arch
> they should get compilation error about undefined macro. Here it will
> be the same thing, only if someone tries to use PT_REGS_PARM1() will
> they reach that _Pragma.
>
> Or am I missing something?

Right! Doing this makes sense regardless of the outcome of our discussion above.

-- 
Lorenz Bauer  |  Systems Engineer
6th Floor, County Hall/The Riverside Building, SE1 7PB, UK

www.cloudflare.com



[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