Re: [PATCH 13/31] bpf tools: Load a program with different instances using preprocessor

From: Wangnan (F)
Date: Sat Oct 31 2015 - 06:43:46 EST




On 2015/10/30 6:44, Arnaldo Carvalho de Melo wrote:
Em Wed, Oct 14, 2015 at 12:41:24PM +0000, Wang Nan escreveu:
In this patch, caller of libbpf is able to control the loaded programs
by installing a preprocessor callback for a BPF program. With
preprocessor, different instances can be created from one BPF program.
Why would one want to do that? I'm new to eBPF, as many other here, I
guess, so giving some more context as to what will this achieve will
help me in processing these patches.

I'll explain at the bottom of this reply.

This patch will be used by perf to generate different prologue for
different 'struct probe_trace_event' instances matched by one
'struct perf_probe_event'.

bpf_program__set_prep() is added to support this feature. Caller
should pass libbpf the number of instances should be created and a
that
preprocessor function which will be called when doing real loading.
the
The callback should return instructions arrays for each instances.
instruction arrays for each instance.
fd field in bpf_programs is replaced by instance, which has an nr field
The fd field in the bpf_programs struct is replaced by instance
(instance of what?)

Instance of program. It is a new concept introduced in
this patch. Before this patch, one program create one fd.
This patch enables one program to create multiple fds. Each
fd is a program instance.

In summary, this and following patches try to solve a important
problem in such tracing tool that: how to access kernel data
in BPF program.

Our core methode on this is BPF prologue that we automatically
generate some BPF asm code for fetching them. However, after we
implement it another problem arises.

We found that there are many cases that multiple entries share
one symbol. Most of the time caused by function inlining. We also
support using glob to match multiple symbol. For example:

SEC("func=my_func_*_abcd arg1")
int func(...) { }

In the above example, it is highly possible that arg1 exist for
all my_func_*_abcd, but in different registers or on different
place in the stack.

When probing, perf would create one tev for each actual probing
point. Due to prologues for fetching arg1 are different, we need
to create multiple BPF prologue (so different BPF fd) for each
probing point. This is why we need this patch: Load a program with
different instances.

I have to admit that the design of this patch is not very easy to
be understand. However I believe it is the best way we can find.
The biggest reason of current design is that I don't want libbpf
be bounded with perf tightly. The prologue generation should be done
by perf, libbpf should never though about it. What it should provide
is to give caller (perf) a way to decorate the BPF binary in multiple
ways for different instances. Therefore I let caller to inject a
helper (preprocessor) for adjusting the code. What the caller need
to tell libbpf is the total instances it want to create, and the
preprocessor should maintain the mapping between the No. of instance
and the binary BPF program it want to create.

For instance, as the caller of libbpf, perf should know how
to generate prologue for my_func_a_abcd and my_func_b_abcd, then it
should maintain a mapping:

No. 0 --> my_func_a_abcd
No. 1 --> my_func_b_abcd

Then it need to tell libbpf that it would create 2 instances of a
BPF program. In the preprocessor perf inject into libbpf, it should
generate prologue for each probing point according to the ID.

Thank you.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/