Re: [RFC PATCH 00/11] bpf, trace, dtrace: DTrace BPF program type implementation and sample use

From: Alexei Starovoitov
Date: Mon Jun 17 2019 - 23:07:12 EST


On Mon, Jun 17, 2019 at 6:54 PM Kris Van Hees <kris.van.hees@xxxxxxxxxx> wrote:
>
> It is not hypothetical. The folowing example works fine:
>
> static int noinline bpf_action(void *ctx, long fd, long buf, long count)
> {
> int cpu = bpf_get_smp_processor_id();
> struct data {
> u64 arg0;
> u64 arg1;
> u64 arg2;
> } rec;
>
> memset(&rec, 0, sizeof(rec));
>
> rec.arg0 = fd;
> rec.arg1 = buf;
> rec.arg2 = count;
>
> bpf_perf_event_output(ctx, &buffers, cpu, &rec, sizeof(rec));
>
> return 0;
> }
>
> SEC("kprobe/ksys_write")
> int bpf_kprobe(struct pt_regs *ctx)
> {
> return bpf_action(ctx, ctx->di, ctx->si, ctx->dx);
> }
>
> SEC("tracepoint/syscalls/sys_enter_write")
> int bpf_tp(struct syscalls_enter_write_args *ctx)
> {
> return bpf_action(ctx, ctx->fd, ctx->buf, ctx->count);
> }
>
> char _license[] SEC("license") = "GPL";
> u32 _version SEC("version") = LINUX_VERSION_CODE;

Great. Then you're all set to proceed with user space dtrace tooling, right?

What you'll discover thought that it works only for simplest things
like above. libbpf assumes that everything in single elf will be used
and passes the whole thing to the kernel.
The verifer removes dead code only from single program.
It disallows unused functions. Hence libbpf needs to start doing
more "linker work" than it does today.
When it loads .o it needs to pass to the kernel only the functions
that are used by the program.
This work should be straightforward to implement.
Unfortunately no one had time to do it.
It's also going to be the first step to multi-elf support.
libbpf would need to do the same "linker work" across .o-s.