Skip to content
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

internal/kconfig: Add possibility to filter kconfig file #1051

Merged
merged 3 commits into from
Jun 8, 2023

Conversation

eiffel-fl
Copy link
Contributor

Hi.

This commit introduces a new arguments to Parse(), it will be used to only add CONFIG_* corresponding to this map key to the returned map.

In this way, it permits reducing memory allocation, by only having CONFIG_* present in the eBPF code and not all the CONFIG_* set for the running kernel. This behavior mimics that of libbpf [1].

In terms of memory allocation, by filtering only with CONFIG_HZ, we reduced allocated bytes by approximately 79%:
BenchmarkParse-8 404 2484446 ns/op 1617336 B/op 9718 allocs/op
BenchmarkParseFiltered-8 751 1582447 ns/op 342272 B/op 9505 allocs/op

Best regards and thank you in advance for the review.

@eiffel-fl eiffel-fl force-pushed the francis/kconfig-memory-optimization branch from 41e779e to 7725053 Compare June 1, 2023 11:02
Copy link
Collaborator

@lmb lmb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good approach. I know that Timo wants to experiment with using a trie, but it's always better to avoid work rather than trying to optimize more.

There are some things we can do to speed this up some more, left a couple of comments.

internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig.go Show resolved Hide resolved
internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig_test.go Outdated Show resolved Hide resolved
@eiffel-fl eiffel-fl force-pushed the francis/kconfig-memory-optimization branch 5 times, most recently from b89366c to e5921de Compare June 6, 2023 14:56
@lmb lmb force-pushed the francis/kconfig-memory-optimization branch from e5921de to 0b4c3fc Compare June 7, 2023 13:15
Copy link
Collaborator

@lmb lmb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a small commit which gets rid of some more allocations. I think that filtered kconfig is now plenty fast:

goos: linux
goarch: amd64
pkg: github.com/cilium/ebpf/internal/kconfig
cpu: 12th Gen Intel(R) Core(TM) i7-1260P
                 │  base.txt   │
                 │   sec/op    │
Parse-16           2.071m ± 3%
ParseFiltered-16   131.6µ ± 1%
geomean            522.1µ

                 │   base.txt   │
                 │     B/op     │
Parse-16           1.433Mi ± 0%
ParseFiltered-16   50.17Ki ± 0%
geomean            271.4Ki

                 │  base.txt   │
                 │  allocs/op  │
Parse-16           7.331k ± 0%
ParseFiltered-16    33.00 ± 0%
geomean             491.9

(NB: Filtered tests against CONFIG_HZ which is fairly high up in the file. Maybe we should choose the last item in config instead?)

@ti-mo are you OK with this approach?

collection.go Outdated Show resolved Hide resolved
@eiffel-fl eiffel-fl force-pushed the francis/kconfig-memory-optimization branch from 0b4c3fc to df89391 Compare June 7, 2023 14:24
@eiffel-fl
Copy link
Contributor Author

Thank you for the approval and the commit but should I squash it with the first one?

(NB: Filtered tests against CONFIG_HZ which is fairly high up in the file. Maybe we should choose the last item in config instead?)

Sure! I can use CONFIG_ARCH_USE_MEMTEST instead!

@lmb
Copy link
Collaborator

lmb commented Jun 7, 2023

should I squash it with the first one?

I'd keep it separate: it has an explanation in the commit message and it makes tracking of code provenance (signed-off-by) easier.

@eiffel-fl
Copy link
Contributor Author

should I squash it with the first one?

I'd keep it separate: it has an explanation in the commit message and it makes tracking of code provenance (signed-off-by) easier.

Then, if we use CONFIG_ARCH_USE_MEMTEST, how should I handle this?
Pushing another commit? Editing one commit and its message?

@lmb
Copy link
Collaborator

lmb commented Jun 7, 2023

Feel free to remove the exact benchmark results from my commit if that helps.

@eiffel-fl eiffel-fl force-pushed the francis/kconfig-memory-optimization branch from df89391 to 2b3b986 Compare June 7, 2023 14:55
@eiffel-fl
Copy link
Contributor Author

OK, I just modified a previous commit and did not touch yours.
Can you please point towards a documentation describing the compiler optimization for string()?

@lmb
Copy link
Collaborator

lmb commented Jun 7, 2023

Here you go: golang/go#3512

Copy link
Collaborator

@ti-mo ti-mo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Left a few nits.

About the approach: I think we're generally more concerned about reducing allocs than reducing CPU usage. Creating garbage has cascading effects and is expensive to clean up, and a larger steady-state memory footprint (e.g. if we parse the whole kconfig and hold onto it) is problematic for many users, given the requests we've gotten for e.g. flushing vmlinux BTF etc. If we can avoid resident memory, let's do it. 🚀

collection.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig_test.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig_test.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig_test.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig_test.go Outdated Show resolved Hide resolved
internal/kconfig/kconfig_test.go Outdated Show resolved Hide resolved
@eiffel-fl eiffel-fl force-pushed the francis/kconfig-memory-optimization branch from 2b3b986 to fd5aebd Compare June 8, 2023 10:45
Copy link
Contributor Author

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review!
I normally addressed everything!

@lmb
Copy link
Collaborator

lmb commented Jun 8, 2023

Please make sure to push formatted files: https://ebpf.semaphoreci.com/jobs/01c36378-27e1-413e-8f2d-d808a315f95e#L722

eiffel-fl and others added 3 commits June 8, 2023 13:48
This commit introduces a new arguments to Parse(), it will be used to only add
CONFIG_* corresponding to this map key to the returned map.

In this way, it permits reducing memory allocation, by only having CONFIG_*
present in the eBPF code and not all the CONFIG_* set for the running kernel.
This behavior mimics that of libbpf [1].

Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
[1]: https://github.com/torvalds/linux/blob/0d85b27b0cc6/tools/lib/bpf/libbpf.c#L1906-L1908
Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
Looking up []byte in map[string]T is usually costly since converting
[]byte to string usually allocates. The compiler has an optimisation
when it's clear that the string is only used for a map lookup.
Refactor processKconfigLine so that we benefit from this optimisation.

    goos: linux
    goarch: amd64
    pkg: github.com/cilium/ebpf/internal/kconfig
    cpu: 12th Gen Intel(R) Core(TM) i7-1260P
                    │  base.txt   │             better.txt             │
                    │   sec/op    │   sec/op     vs base               │
    ParseFiltered-16   148.0µ ± 4%   130.6µ ± 3%  -11.75% (p=0.002 n=6)

                    │   base.txt   │             better.txt              │
                    │     B/op     │     B/op      vs base               │
    ParseFiltered-16   59.29Ki ± 0%   50.17Ki ± 0%  -15.38% (p=0.002 n=6)

                    │  base.txt   │            better.txt             │
                    │  allocs/op  │ allocs/op   vs base               │
    ParseFiltered-16   400.00 ± 0%   33.00 ± 0%  -91.75% (p=0.002 n=6)

Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
@eiffel-fl eiffel-fl force-pushed the francis/kconfig-memory-optimization branch from fd5aebd to 652e080 Compare June 8, 2023 12:48
@eiffel-fl
Copy link
Contributor Author

Please make sure to push formatted files: https://ebpf.semaphoreci.com/jobs/01c36378-27e1-413e-8f2d-d808a315f95e#L722

Sorry 😅 😅 😅!
Now it should do the trick!

@lmb lmb merged commit 9444f0c into cilium:master Jun 8, 2023
@eiffel-fl eiffel-fl deleted the francis/kconfig-memory-optimization branch June 8, 2023 13:00
@eiffel-fl
Copy link
Contributor Author

Thank you for the merge and the reviews!

@lmb
Copy link
Collaborator

lmb commented Jun 8, 2023

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants