ringbuf: add zero-copy reader callback API#1930
ringbuf: add zero-copy reader callback API#1930jschwinger233 wants to merge 1 commit intocilium:mainfrom
Conversation
Introduce Reader.ReadZeroCopy to process samples directly from the ring buffer via a callback. Refactor the reader to share the same polling loop between ReadInto and ReadZeroCopy, and add ringReader.readRecordZeroCopy as the internal zero-copy path, with readRecord delegating to it. Benchmarks (80–2048B) show zero-copy is flat at small sizes and scales much better for larger records, reaching up to 5.63x speedup. Signed-off-by: graymon <greyschwinger@gmail.com>
|
|
||
| // ReadZeroCopy reads the next record from the BPF ringbuf using a zero-copy callback. | ||
| // The sample slice is only valid until the callback returns. | ||
| func (r *Reader) ReadZeroCopy(f func(sample []byte, remaining int) error) error { |
There was a problem hiding this comment.
Following the code, I think this function has the potential be used incorrectly?
var saved []byte
reader.ReadZeroCopy(func(sample []byte, remaining int) error {
saved = sample // retains reference to temporary memory?
return nil
})
// is saved still valid at this point?
|
Hi @jschwinger233 , thanks for introducing this. @florianl - your comment makes sense, this API should stay safe. For this reason I implemented a similar idea, but after using |
|
e2manyproposals, let's continue the conversation in #1968. |
Ringbuf reads currently copy every sample into a user buffer via Read/ReadInto, even when callers only need to inspect data once. This change adds a zero-copy read API so consumers can process records directly from the mmap-backed ring buffer without an intermediate copy.
Changes
API/behavior notes
Benchmarks[1]
Results below are from benchmark-result.txt (read-into copy vs read-view zero-copy). Event sizes cover 80–2048 bytes in 16-byte steps (124 sizes).
Sample sizes (Mevents/s):
[1] https://github.com/jschwinger233/bpf_ringbuf_zc_benchmark