Skip to content

Conversation

@fabled
Copy link
Contributor

@fabled fabled commented Nov 9, 2025

Convert the ebpf frame structure to variable length interpreter specific data. This has the benefit of using less data for many frame types, but also allow sending more data if it benefits the interpreter.

Set the frame data maximum to 3kB uint64:s to allow large traces.
Update the tracer to do frame caching to not pressure GC too much.

fixes #940

includes also PR #749 so that should be merged first (keeping this as a draft until its merged)

- use unique FrameMappingData to reduce the Frame size
- construct FrameMappingData directly from the cached ELF info
- remove the FileID LRU cache as unneeded
- replace processmnanager.processInfo.mappings map with a sorted
  slice of the []Mappings
- atomically do batch updates of the []Mappings
- remove processmanager.processInfo.mappingsByFileID as redudant

TODO:
- eim should probably get libpf.FrameMappingFile instead of host.FileID
- eventually move processmanager.Mapping to interpreters and pass it
  as the mapping type
- use slices.SortFunc
- add mapping.Length to processmanager Mapping
- move sorting and publishing of changed mappings *after* the
  handling of the ebpf modifications -> the sort reordered things
  and mpAdd pointers point to wrong data
- don't hold lock during interpreter synchronize mappings call
stdout is line cached. its glibc extension that reading stdin
flushes stdout, but its not standard. fix test case to explicitly
flush stdout.
@fabled fabled force-pushed the tt-variable-length-frame branch 5 times, most recently from 5017685 to b915153 Compare November 9, 2025 16:05
Convert the ebpf frame structure to variable length interpreter
specific data. This has the benefit of using less data for many
frame types, but also allow sending more data if it benefits
the interpreter.

Set the frame data maximum to 3kB uint64:s to allow large traces.
Update the tracer to do frame caching to not pressure GC too much.
@fabled fabled force-pushed the tt-variable-length-frame branch from b915153 to dd14424 Compare November 9, 2025 16:15

// The frames of the stack trace.
Frame frames[MAX_FRAME_UNWINDS];
u64 frame_data[3072];
Copy link
Contributor

@dalehamel dalehamel Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to also add a check to the size of the overall PerCPURecord struct, which seems to be 32768, eg:

// https://github.com/torvalds/linux/blob/e9a6fb0bcdd7609be6969112f3fbfcce3b1d4a7c/include/linux/percpu.h#L24C39-L24C47
_Static_assert(sizeof(PerCPURecord) <= (32 << 10), "Per CPU record too large")

AFAICT, this is where the limit for a per cpu record is defined:

https://github.com/torvalds/linux/blob/e9a6fb0bcdd7609be6969112f3fbfcce3b1d4a7c/include/linux/percpu.h#L24C39-L24C47

And here is where the check seems to happen:

https://github.com/torvalds/linux/blob/4ea7c1717f3f2344f7a1cdab4f5875cfa89c87a9/kernel/bpf/arraymap.c#L77-L79

I validated this (on main) by increasing the size of the Frame buffer. It is able to load the program with a frame buffer size of 1285, and a total size of exactly 32 << 10

time=2025-11-10T12:59:37.444-05:00 level=WARN msg="per_cpu_records, PerCPUArray(keySize=4, valueSize=32768, maxEntries=1, flags=0)"

but fails with 1286:

time=2025-11-10T13:00:30.257-05:00 level=WARN msg="per_cpu_records, PerCPUArray(keySize=4, valueSize=32792, maxEntries=1, flags=0)"
time=2025-11-10T13:00:30.258-05:00 level=ERROR msg="Failed to start agent controller: failed to load eBPF tracer: failed to load eBPF code: failed to load eBPF maps: failed to load per_cpu_records: creating map: map create: cannot allocate memory"

This buffer is the largest factor in that, taking up 24576 bytes, but we still have some room to potentially increase this (though, should leave room for additions to other struct members of PerCPURecord)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert ebpf trace struct frame to variable length data

2 participants