Skip to content

Commit

Permalink
tetragon: Factor max entries setup
Browse files Browse the repository at this point in the history
Centralizing maps 'has' config into hasMaps object,
which gets initialized before we create the sensor
and checked when we create sensor maps.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
  • Loading branch information
olsajiri committed Jun 26, 2024
1 parent 2fabfd1 commit 2455cde
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 29 deletions.
69 changes: 41 additions & 28 deletions pkg/sensors/tracing/generickprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,12 @@ func filterMaps(load *program.Program, pinPath string, kprobeEntry *genericKprob
return maps
}

func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID, enableFDInstall bool) ([]*program.Program, []*program.Map, error) {
func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.EntryID, has hasMaps) ([]*program.Program, []*program.Map, error) {
var multiRetIDs []idtable.EntryID
var progs []*program.Program
var maps []*program.Map

data := &genericKprobeData{}
oneKprobeHasStackTrace := false
oneKprobeHasRatelimit := false

for _, id := range multiIDs {
gk, err := genericKprobeTableGet(id)
Expand All @@ -289,9 +287,10 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
if gk.loadArgs.retprobe {
multiRetIDs = append(multiRetIDs, id)
}
oneKprobeHasStackTrace = oneKprobeHasStackTrace || gk.hasStackTrace
oneKprobeHasRatelimit = oneKprobeHasRatelimit || gk.hasRatelimit
gk.data = data

has.stackTrace = has.stackTrace || gk.hasStackTrace
has.rateLimit = has.rateLimit || gk.hasRatelimit
}

loadProgName := "bpf_multi_kprobe_v53.o"
Expand All @@ -316,7 +315,7 @@ 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 {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -345,7 +344,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E
maps = append(maps, matchBinariesPaths)

stackTraceMap := program.MapBuilderPin("stack_trace_map", sensors.PathJoin(pinPath, "stack_trace_map"), load)
if oneKprobeHasStackTrace {
if has.stackTrace {
stackTraceMap.SetMaxEntries(stackTraceMapMaxEntries)
}
maps = append(maps, stackTraceMap)
Expand All @@ -358,7 +357,7 @@ func createMultiKprobeSensor(sensorPath, policyName string, multiIDs []idtable.E

if kernels.EnableLargeProgs() {
ratelimitMap := program.MapBuilderPin("ratelimit_map", sensors.PathJoin(pinPath, "ratelimit_map"), load)
if oneKprobeHasRatelimit {
if has.rateLimit {
ratelimitMap.SetMaxEntries(ratelimitMapMaxEntries)
}
maps = append(maps, ratelimitMap)
Expand Down Expand Up @@ -396,7 +395,7 @@ 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 {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -552,6 +551,23 @@ func getKprobeSymbols(symbol string, syscall bool, lists []v1alpha1.ListSpec) ([
return []string{symbol}, syscall, nil
}

type hasMaps struct {
stackTrace bool
rateLimit bool
fdInstall bool
}

func hasMapsSetup(spec *v1alpha1.TracingPolicySpec) hasMaps {
has := hasMaps{}
for _, kprobe := range spec.KProbes {
if selectorsHaveFDInstall(kprobe.Selectors) {
has.fdInstall = true
break
}
}
return has
}

func createGenericKprobeSensor(
spec *v1alpha1.TracingPolicySpec,
name string,
Expand Down Expand Up @@ -585,16 +601,6 @@ 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 All @@ -604,6 +610,8 @@ func createGenericKprobeSensor(
selMaps: selMaps,
}

has := hasMapsSetup(spec)

for i := range kprobes {
syms, syscall, err := getKprobeSymbols(kprobes[i].Call, kprobes[i].Syscall, lists)
if err != nil {
Expand All @@ -623,9 +631,9 @@ func createGenericKprobeSensor(
}

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

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

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

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

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), load)
if enableFDInstall {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand Down Expand Up @@ -921,7 +929,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
// anonymous map (as it's always used by the BPF prog) and is clearly linked
// to tetragon
stackTraceMap := program.MapBuilderPin("stack_trace_map", sensors.PathJoin(pinPath, "stack_trace_map"), load)
if kprobeEntry.hasStackTrace {
if has.stackTrace {
// to reduce memory footprint however, the stack map is created with a
// max entry of 1, we need to expand that at loading.
stackTraceMap.SetMaxEntries(stackTraceMapMaxEntries)
Expand All @@ -936,7 +944,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,

if kernels.EnableLargeProgs() {
ratelimitMap := program.MapBuilderPin("ratelimit_map", sensors.PathJoin(pinPath, "ratelimit_map"), load)
if kprobeEntry.hasRatelimit {
if has.rateLimit {
// similarly as for stacktrace, we expand the max size only if
// needed to reduce the memory footprint when unused
ratelimitMap.SetMaxEntries(ratelimitMapMaxEntries)
Expand Down Expand Up @@ -978,7 +986,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
maps = append(maps, callHeap)

fdinstall := program.MapBuilderPin("fdinstall_map", sensors.PathJoin(sensorPath, "fdinstall_map"), loadret)
if enableFDInstall {
if has.fdInstall {
fdinstall.SetMaxEntries(fdInstallMapMaxEntries)
}
maps = append(maps, fdinstall)
Expand All @@ -994,7 +1002,7 @@ func createKprobeSensorFromEntry(kprobeEntry *genericKprobe, sensorPath string,
return progs, maps
}

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

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

// setup per kprobe map config
has.stackTrace = gk.hasStackTrace
has.rateLimit = gk.hasRatelimit

progs, maps = createKprobeSensorFromEntry(gk, sensorPath, progs, maps, has)
}

return progs, maps, nil
Expand Down
6 changes: 5 additions & 1 deletion pkg/sensors/tracing/generictracepoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ func createGenericTracepointSensor(
progName = "bpf_generic_tracepoint_v53.o"
}

has := hasMaps{}

maps := []*program.Map{}
progs := make([]*program.Program, 0, len(tracepoints))
for _, tp := range tracepoints {
Expand All @@ -406,11 +408,13 @@ func createGenericTracepointSensor(
return nil, fmt.Errorf("failed to initialize tracepoint kernel selectors: %w", err)
}

has.fdInstall = selectorsHaveFDInstall(tp.Spec.Selectors)

prog0.LoaderData = tp.tableIdx
progs = append(progs, prog0)

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

0 comments on commit 2455cde

Please sign in to comment.