ebpf
                                
                                 ebpf copied to clipboard
                                
                                    ebpf copied to clipboard
                            
                            
                            
                        [RFC] [PoC] btf: LoadSpecFromReader: add filter param to optimize memory
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:
After:
It works with parsing the BTF file in two passes:
- read sequentially the BTF file to get offsets of each BTF type and mark those we want to keep
- 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