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

[RFC] [PoC] btf: LoadSpecFromReader: add filter param to optimize memory #1589

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alban
Copy link
Contributor

@alban alban commented Oct 17, 2024

This is a proof-of-concept. The code is not ready for merging but it shows it is possible to significantly reduce the memory consumption (by 27MB).


In the new LoadSpecFromReader, I added a filter parameter to only parse required kernel btf types.

type TypeFilter struct {
       Names map[string]bool
}

func LoadSpecFromReader(rd io.ReaderAt, filter *TypeFilter) (*Spec, error)

Users of the cilium/ebpf package can get the list of relocations they programs require and give it to LoadKernelSpecWithFilter:

var filter *btf.TypeFilter
if len(programs) > 0 {
        filter = &btf.TypeFilter{
                Names: map[string]bool{},
        }
        for _, p := range programs {
                iter := p.Instructions.Iterate()
                for iter.Next() {
                        if relo := btf.CORERelocationMetadata(iter.Ins); relo != nil {
                                fmt.Printf("relo %s\n", relo.String())
                                filter.Names[relo.TypeName()] = true
                        }
                }
        }
}
s, err := btf.LoadKernelSpecWithFilter(filter)
...
opts := ebpf.CollectionOptions{
	Programs: ebpf.ProgramOptions{
		KernelTypes: s,
	},
}
...
if err := spec.LoadAndAssign(objs, &opts); err != nil {

In my tests in Inspektor Gadget (with this branch), pprof flamegraph inuse_space shows a reduction of memory usage from 40MB to 12MB: btf.LoadKernelSpec() is completely removed from the flamegraph. It used to take 27MB.

Before:

image

After:

image


It works with parsing the BTF file in two passes:

  1. read sequentially the BTF file to get offsets of each BTF type and mark those we want to keep
  2. parse the types we want to keep at the offsets found in the previous steps and follow the type dependency graph.

@burak-ok @mauriciovasquezbernal @flyth

…el btf types

bpf programs can specify which types they care about. Other types are
not instantiated.

In my tests in Inspektor Gadget, pprof flamegraph inuse_space shows a
reduction of memory usage from 40MB to 12MB: btf.LoadKernelSpec() is
completely removed from the flamegraph. It used to take 27MB.

Signed-off-by: Alban Crequy <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Changes exported API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant