Skip to content

Commit 267ee9a

Browse files
committed
Increase maximum frames and make maximum tail calls configurable
1 parent 3472d3a commit 267ee9a

11 files changed

Lines changed: 24 additions & 9 deletions

File tree

internal/controller/controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020

2121
const MiB = 1 << 20
2222

23+
const MaxTailCalls = 29
24+
2325
// Controller is an instance that runs, manages and stops the agent.
2426
type Controller struct {
2527
config *Config
@@ -85,6 +87,7 @@ func (c *Controller) Start(ctx context.Context) error {
8587
ProbabilisticInterval: c.config.ProbabilisticInterval,
8688
ProbabilisticThreshold: c.config.ProbabilisticThreshold,
8789
OffCPUThreshold: uint32(c.config.OffCPUThreshold),
90+
MaxTailCalls: MaxTailCalls,
8891
})
8992
if err != nil {
9093
return fmt.Errorf("failed to load eBPF tracer: %w", err)

support/ebpf/tracemgmt.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ static inline PerCPURecord *get_per_cpu_record(void)
204204
static inline PerCPURecord *get_pristine_per_cpu_record()
205205
{
206206
PerCPURecord *record = get_per_cpu_record();
207+
int key0 = 0;
208+
SystemConfig *syscfg = bpf_map_lookup_elem(&system_config, &key0);
209+
if (!syscfg)
210+
return NULL;
207211
if (!record)
208212
return record;
209213

@@ -235,7 +239,7 @@ static inline PerCPURecord *get_pristine_per_cpu_record()
235239
record->luajitUnwindState.cframe = 0;
236240
record->luajitUnwindState.is_jit = false;
237241
record->unwindersDone = 0;
238-
record->tailCalls = 0;
242+
record->tailCallsRemaining = syscfg->max_tail_calls;
239243
record->ratelimitAction = RATELIMIT_ACTION_DEFAULT;
240244
record->customLabelsState.go_m_ptr = NULL;
241245

@@ -516,8 +520,8 @@ static inline __attribute__((__always_inline__)) void tail_call(void *ctx, int n
516520
return;
517521
}
518522

519-
if (record->tailCalls >= 29) {
520-
// The maximum tail call count we need to support on older kernels is 32. At this point
523+
if (!record->tailCallsRemaining) {
524+
// At this point
521525
// there is a chance that continuing unwinding the stack would further increase the number of
522526
// tail calls. As a result we might lose the unwound stack as no further tail calls are left
523527
// to report it to user space. To make sure we do not run into this issue we stop unwinding
@@ -526,7 +530,7 @@ static inline __attribute__((__always_inline__)) void tail_call(void *ctx, int n
526530
record->state.unwind_error = ERR_MAX_TAIL_CALLS;
527531
increment_metric(metricID_MaxTailCalls);
528532
}
529-
record->tailCalls += 1;
533+
--record->tailCallsRemaining;
530534

531535
bpf_tail_call(ctx, &perf_progs, next);
532536
}
8.79 KB
Binary file not shown.
8.75 KB
Binary file not shown.
5.55 KB
Binary file not shown.
3.93 KB
Binary file not shown.

support/ebpf/types.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ typedef enum TraceOrigin {
386386
// MAX_FRAME_UNWINDS defines the maximum number of frames per
387387
// Trace we can unwind and respect the limit of eBPF instructions,
388388
// limit of tail calls and limit of stack size per eBPF program.
389-
#define MAX_FRAME_UNWINDS 128
389+
#define MAX_FRAME_UNWINDS 256
390390

391391
// MAX_NON_ERROR_FRAME_UNWINDS defines the maximum number of frames
392392
// to be pushed by unwinders while still leaving space for an error frame.
@@ -886,7 +886,7 @@ typedef struct PerCPURecord {
886886
u32 unwindersDone;
887887

888888
// tailCalls tracks the number of calls to bpf_tail_call().
889-
u8 tailCalls;
889+
u8 tailCallsRemaining;
890890

891891
// ratelimitAction determines the PID event rate limiting mode
892892
u8 ratelimitAction;
@@ -1051,6 +1051,9 @@ typedef struct SystemConfig {
10511051

10521052
// Enables the temporary hack that drops pure errors frames in unwind_stop.
10531053
bool drop_error_only_traces;
1054+
1055+
// Maximum number of eBPF tail calls before giving up.
1056+
u8 max_tail_calls;
10541057
} SystemConfig;
10551058

10561059
// Avoid including all of arch/arm64/include/uapi/asm/ptrace.h by copying the

support/types.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testutils/helpers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func StartTracer(ctx context.Context, t *testing.T, et tracertypes.IncludedTrace
5050
SamplesPerSecond: 20,
5151
ProbabilisticInterval: 100,
5252
ProbabilisticThreshold: 100,
53+
MaxTailCalls: 29,
5354
})
5455
require.NoError(t, err)
5556

tracer/systemconfig.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ func determineStackLayout(coll *cebpf.CollectionSpec, maps map[string]*cebpf.Map
227227

228228
func loadSystemConfig(coll *cebpf.CollectionSpec, maps map[string]*cebpf.Map,
229229
kernelSymbols *libpf.SymbolMap, includeTracers types.IncludedTracers,
230-
offCPUThreshold uint32, filterErrorFrames bool) error {
230+
offCPUThreshold uint32, filterErrorFrames bool,
231+
maxTailCalls uint8) error {
231232
pacMask := pacmask.GetPACMask()
232233
if pacMask != 0 {
233234
log.Infof("Determined PAC mask to be 0x%016X", pacMask)
@@ -238,6 +239,7 @@ func loadSystemConfig(coll *cebpf.CollectionSpec, maps map[string]*cebpf.Map,
238239
inverse_pac_mask: ^C.u64(pacMask),
239240
drop_error_only_traces: C.bool(filterErrorFrames),
240241
off_cpu_threshold: C.u32(offCPUThreshold),
242+
max_tail_calls: C.u8(maxTailCalls),
241243
}
242244

243245
if err := parseBTF(&syscfg); err != nil {

0 commit comments

Comments
 (0)