New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aot: Enable aot built bpftrace programs to run on their own #3104
base: master
Are you sure you want to change the base?
Conversation
80c876d
to
c5aa371
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall looks reasonable. i'm assuming this involved some nice debugging work :)
1b30ca2
to
2f79f41
Compare
Addressed comments, thanks! |
src/aot/aot.cpp
Outdated
Elf_Data *data = NULL; | ||
uint8_t *btaot_section = NULL; | ||
const Header *hdr; | ||
int i = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can we move this closer to the while loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I put it here (along with the others) because of the goto statements bypassing initialization errors. But I can split the initialization onto a second line to make it work.
Address comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that we can't store a cstring_view in the serialised data now - just got a couple of other places that we can still reduce string copying in
05ba971
to
fbad3cf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking pretty good to me, just a couple of minor points.
What's the testing situation looking like for AOT? It'd be good to have it exercised by the runtime test suite to ensure it doesn't break again
Address comments and rebase.
The immediate next order of business to enable this PoC will be to get |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Yeah, one of the items on the list in #2918 is to re-remove the large list of runtime deps from the shim, which should hopefully help a lot.
I believe
Probably not ready to add to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, sorry for the delayed review! I really like this work and hope that we'll be able to get it in soon. With that, I apologize if the following will cause any delays but I think that it's an important thing to mention.
I think that there's a major flaw in the way we serialize bytecode at the moment. The current workflow is:
- codegen -> ELF -> BpfBytecode -> serialization to .btaot
- deserialization from .btaot -> BpfBytecode -> load BPF programs
With the upcoming move to libbpf, this will not let us leverage the full power of libbpf which is able to deduce a lot of information about the BPF maps and programs from the ELF. I think that the correct workflow should be:
- codegen -> ELF -> serialization to .btaot
- deserialization from .btaot -> ELF -> BpfBytecode -> load BPF programs
This is also the reason why you had to serialize BpfMap
which I specifically tried to avoid when I was implementing it. Ideally, BpfMap
instances should be created by running libbpf parsing on the ELF produced by bpftrace.
In addition, I plan to drop BpfBytecode.sections_
completely and use libbpf's struct bpf_object
instead (which is created from the ELF). When that happens, the current AOT approach would stop working and we'd have to move to the workflow suggested above anyways.
So, I suggest we move to serializing the produced ELF instead of BpfBytecode
before merging this PR.
Hi Viktor, thanks for the comment. You make good points, and I forgot to consider your work moving bpftrace to use libbpf when opening this PR. Given what you said about removing |
Thanks @arthurshau! I think that it could be as simple as serializing the ELF produced by codegen (as raw binary data) and moving creation of |
3d86e50
to
afa9814
Compare
@viktormalik Sorry for the delay, I've implemented the requested changes. Can you double check that the serialization portion in particular is done correctly? I basically just call Also, when running the generated binary, I'm now getting these libbpf warnings for some reason:
This happens when calling |
Just had a quick skim, but we should try and keep the ELF file in memory until the actual serialisation step.
|
53eee74
to
4c198fe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of small remarks, otherwise looks great. Thanks for this work!
Addressed comments, thanks! Also moved the |
Fixes a couple issues with aot built binaries that was preventing runtime from functioning. Namely, we were looking in the wrong place in the ELF file for the custom .btaot section that we added. We were also not serializing the map of BpfMaps contained in BpfBytecode, which is necessary for runtime. Finally, I fixed maps not being printed out correctly when bpftrace exits.
Currently, even though we make a copy of the runtime shim and then embed the necessary metadata + bytecode into the binary, you still need to pass that binary as an argument to the runtime shim in order to run it (i.e. you need to do 'bpftrace-aotrt <file_name>'). Since the binary can fully function on its own, we don't need to do this anymore. This commit makes the executable just look inside itself for the metadata and bytecode, skipping the need to call bpftrace-aotrt. (i.e. you can now run the binary with just ./<file_name>.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I'm just not approving the PR, yet, as I'd like to take some time trying this out.
Yeah, makes sense.
Yes, that should be correct.
I'm not sure why this is happening but I'm seeing this when running in non-AOT mode, too. It's certainly something that we should address but it shouldn't be caused by this PR. |
🚀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basic probes work nice, some others don't but since this is still undocumented, I'm ok with merging this as-is and fixing things in the follow-up work.
My remarks:
- Using
--aot
searches$PATH
forbpftrace-aotrt
which is not very convenient when doing development. Maybe we could make it also (recursively) search$PWD
(or the directory of thebpftrace
binary) so that developers don't have to update their$PATH
manually? - BTF-based probes (e.g.
kfunc
) currently do not work b/c the AOT main doesn't runbpftrace.parse_btf()
. Here, it'll be tricky to support kernel modules as in normal mode, we parse the probes to determine which kernel modules BTF needs to be parsed. Since we don't have that information in pre-compiled binary, we'll have to figure out a different way to get the list of modules that the program may attach to. - Since this will likely get merged shortly before we do the new release, I just want to make sure that we agree that we're leaving this undocumented for now.
Sounds good, I agree with that. |
Yeah, need to find a better way.
Agreed. We don't wanna document / announce anything until at least #2918 is completed. |
The first commit fixes a couple issues with aot built binaries that was preventing runtime from functioning.
We now look in the right place in the ELF file for the custom .btaot section that contains the metadata + generated ELF, that we then restore to create BpfBytecode.
Second, we now also serialize the map of BpfMaps owned by BpfBytecode into the bytecode as well, which is necessary for runtime. In order to do this, I needed to add a default constructor to BpfMap, as well as a hacky solution to be able to serialize the name of the map which is a cstring_view (which may or may not have defeated the purpose of having the cstring_view in the first place - would appreciate a review of this).Finally, I fixed maps not being printed out correctly when bpftrace exits.The second commit allows running aot binaries directly without calling having to call runtime shim (e.g. you can now just call
./a.btaot
instead ofbpftrace-aotrt a.btaot
. This is possible because the aot binaries already contain all the info necessary to run themselves.Address part 1 of #2918.
Example:
Checklist
man/adoc/bpftrace.adoc
CHANGELOG.md