Skip to content

Commit

Permalink
pkg/sensors: reduce memory footprint of unused fdinstall maps
Browse files Browse the repository at this point in the history
Resize the fdinstall_map if needed to save memory, thus we are saving
~11MB of kernel memory by kprobe that are not using FollowFD, UnfollowFD
or CopyFD.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
  • Loading branch information
mtardy committed Jun 19, 2024
1 parent 1bfd8bf commit 2631f9b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
2 changes: 1 addition & 1 deletion bpf/process/types/basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1777,7 +1777,7 @@ struct fdinstall_value {

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 32000);
__uint(max_entries, 1); // will be resized by agent when needed
__type(key, struct fdinstall_key);
__type(value, struct fdinstall_value);
} fdinstall_map SEC(".maps");
Expand Down
48 changes: 42 additions & 6 deletions pkg/sensors/tracing/generickprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const (
// much kernel memory when enabled.
stackTraceMapMaxEntries = 32768
ratelimitMapMaxEntries = 32768
fdInstallMapMaxEntries = 32000
)

func kprobeCharBufErrorToString(e int32) string {
Expand Down Expand Up @@ -271,7 +272,7 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob
return maps
}

func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID) ([]*program.Program, []*program.Map, error) {
func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID, enableFDInstall bool) ([]*program.Program, []*program.Map, error) {
var multiRetIDs []idtable.EntryID
var progs []*program.Program
var maps []*program.Map
Expand Down Expand Up @@ -315,6 +316,9 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
progs = append(progs, load)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load)
if enableFDInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)

configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load)
Expand Down Expand Up @@ -392,6 +396,9 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
maps = append(maps, callHeap)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret)
if enableFDInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)

socktrack := program.MapBuilderPin("socktrack_map", sensors.PathJoin(sensorPath, "socktrack_map"), loadret)
Expand Down Expand Up @@ -578,6 +585,16 @@ func createGenericKprobeSensor(
selMaps = &selectors.KernelSelectorMaps{}
}

// detect at the policy level if one kprobe uses the fdinstall feature since
// the map is shared amongst all kprobes
oneKprobeHasFDInstall := false
for _, kprobe := range kprobes {
if selectorsHaveFDInstall(kprobe.Selectors) {
oneKprobeHasFDInstall = true
break
}
}

in := addKprobeIn{
useMulti: useMulti,
sensorPath: name,
Expand Down Expand Up @@ -606,9 +623,9 @@ func createGenericKprobeSensor(
}

if useMulti {
progs, maps, err = createMultiKprobeSensor(in.sensorPath, in.policyName, ids)
progs, maps, err = createMultiKprobeSensor(in.sensorPath, in.policyName, ids, oneKprobeHasFDInstall)
} else {
progs, maps, err = createSingleKprobeSensor(in.sensorPath, ids)
progs, maps, err = createSingleKprobeSensor(in.sensorPath, ids, oneKprobeHasFDInstall)
}

if err != nil {
Expand Down Expand Up @@ -845,7 +862,7 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idt
}

func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
progs []*program.Program, maps []*program.Map) ([]*program.Program, []*program.Map) {
progs []*program.Program, maps []*program.Map, enableFDInstall bool) ([]*program.Program, []*program.Map) {

loadProgName, loadProgRetName := kernels.GenericKprobeObjs()
isSecurityFunc := strings.HasPrefix(kprobeEntry.funcName, "security_")
Expand All @@ -867,6 +884,9 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
progs = append(progs, load)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load)
if enableFDInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)

configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load)
Expand Down Expand Up @@ -958,6 +978,9 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
maps = append(maps, callHeap)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret)
if enableFDInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)

if kernels.EnableLargeProgs() {
Expand All @@ -971,7 +994,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
return progs, maps
}

func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID) ([]*program.Program, []*program.Map, error) {
func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID, enableFDInstall bool) ([]*program.Program, []*program.Map, error) {
var progs []*program.Program
var maps []*program.Map

Expand All @@ -981,7 +1004,7 @@ func createSingleKprobeSensor(sensorPath string, ids []idtable.EntryID) ([]*prog
return nil, nil, err
}
gk.data = &genericKprobeData{}
progs, maps = createKprobeSensorFromEntry(gk, sensorPath, progs, maps)
progs, maps = createKprobeSensorFromEntry(gk, sensorPath, progs, maps, enableFDInstall)
}

return progs, maps, nil
Expand Down Expand Up @@ -1320,3 +1343,16 @@ func selectorsHaveStackTrace(selectors []v1alpha1.KProbeSelector) bool {
}
return false
}

func selectorsHaveFDInstall(sel []v1alpha1.KProbeSelector) bool {
for _, selector := range sel {
for _, matchAction := range selector.MatchActions {
if a := selectors.ActionTypeFromString(matchAction.Action); a == selectors.ActionTypeFollowFd ||
a == selectors.ActionTypeUnfollowFd ||
a == selectors.ActionTypeCopyFd {
return true
}
}
}
return false
}
3 changes: 3 additions & 0 deletions pkg/sensors/tracing/generictracepoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ func createGenericTracepointSensor(
progs = append(progs, prog0)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(pinPath, "fdinstall_map"), prog0)
if selectorsHaveFDInstall(tp.Spec.Selectors) {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)

tailCalls := program.MapBuilderPin("tp_calls", sensors.PathJoin(pinPath, "tp_calls"), prog0)
Expand Down

0 comments on commit 2631f9b

Please sign in to comment.