-
Notifications
You must be signed in to change notification settings - Fork 731
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
Load kernel BTF spec once when creating a new collection #1690
base: main
Are you sure you want to change the base?
Load kernel BTF spec once when creating a new collection #1690
Conversation
When creating a new collection without specifying the `KernelTypes` in the `ProgramOptions`, the kernel BTF is implicitly loaded. For this the `btf.LoadKernelSpec()` helper is used. Even though the spec is only loaded once, this operation cause a lot of memory churn, as the kernel spec is being copied each time the function get called. This becomes an issue when a collection with lots of programs is loaded in a resource limited environment. This commit initializes an missing `KernelTypes` field with the BTF kernel spec, getting rid of the subsequent calls of `BTF.Copy()`. This greatly reduces the number of allocations/op when running the `BenchmarkNewCollectionManyProgs` benchmark. Here are the results: Previous: BenchmarkNewCollectionManyProgs-4 12 98443414 ns/op 116779863 B/op 403964 allocs/op With optimization: BenchmarkNewCollectionManyProgs-4 184 5807742 ns/op 4134444 B/op 17325 allocs/op Signed-off-by: Patrick Pichler <[email protected]>
345d0ed
to
fed5496
Compare
@lmb @dylandreimerink I know the test for kernels without BTF support are failing. I guess this can be fixed by lazy loading the kernel spec only once. Before I start refactoring the code though, is this approach something you would merge? A different approach might be to refactor the |
IIRC we don't really copy the full spec. It's a shallow, lazy copy. Is that still too expensive?
The problem with this is that it always causes a parse of kernel BTF, even in cases where the load wouldn't have needed one. |
Ok after looking at the flame graphs again, I think the issue is not directly the copying of the kernel BTF spec, but since each time relocations get applied, they call An alternative could be, to use the type directly from the What do you think about this solution? |
Sorry for the late reply. The culprit for you is always CO-RE relocation? I think we could extend your approach to add an unexported method |
No worries! From what I've traced, CO-RE is causing the churn yeah. I guess the As for the test, what quickly comes to my mind would be to create a forced deep copy of the BTF spec (I guess a new method is needed here), load the program and then compare if the specs are the same. From what I see only CO-RE should be the issue, as the other place where BTF types are queried by IDs are in the |
It would have to:
I think that could work, but maybe it's enough to copy |
Sounds good! |
When creating a new collection without specifying the
KernelTypes
in theProgramOptions
, the kernel BTF is implicitly loaded. For this thebtf.LoadKernelSpec()
helper is used. Even though the spec is only loaded once, this operation cause a lot of memory churn, as the kernel spec is being copied each time the function get called. This becomes an issue when a collection with lots of programs is loaded in a resource limited environment.This commit initializes an missing
KernelTypes
field with the BTF kernel spec, getting rid of the subsequent calls ofBTF.Copy()
.This greatly reduces the number of allocations/op when running the
BenchmarkNewCollectionManyProgs
benchmark. Here are the results:Previous:
BenchmarkNewCollectionManyProgs-4 12 98443414 ns/op 116779863 B/op 403964 allocs/op
With optimization:
BenchmarkNewCollectionManyProgs-4 184 5807742 ns/op 4134444 B/op 17325 allocs/op