-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Design proposal for new ring buffer API #3848
base: main
Are you sure you want to change the base?
Conversation
Converting to draft while I make a few design updates. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix the sample code. Its broken as it will not work correctly on weakly ordered systems (ARM64 as an example).
Splits the design so callback consumers use the existing libbpf APIs, and mapped memory consumers use the new windows-specific functions.
docs/RingBuffer.md
Outdated
|
||
If the `RINGBUF_FLAG_NO_AUTO_CALLBACK` flag is set, callbacks will not automatically be called and `ring_buffer__poll()` | ||
should be called to poll for available data and invoke the callback. On Windows a timeout of zero can be passed to | ||
`ring_buffer__poll()` to get the same behaviour as `ring_buffer__consume()`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the proposed behavior if ring_buffer__consume()
is called when the RINGBUF_FLAG_NO_AUTO_CALLBACK
flag is set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This proposal only includes ring_buffer__poll()
(not consume) - That note explains that ring_buffer__poll(X,0)
is functionally equivalent to ring_buffer__consume(X)
## Overview | ||
|
||
The current ringbuffer uses a pure callback-based approach to reading the ringbuffer. | ||
Linux also supports memory-mapped polling consumers, which can't be directly supported in the current model. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if you try to port code to do so? Would it fail to compile, compile and crash when run, compile and have some other behavior when run, or what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The APIs to support a memory mapped consumer are not currently exposed, so you wouldn't be able to compile it.
The current implementation uses locking to serialize producers and consumers and doesn't expose the producer page in the memory mapping, so you couldn't have a linux-style consumer that directly reads/writes the producer/consumer offsets and can tell when the next record is ready.
docs/RingBuffer.md
Outdated
On Windows asynchronous events are supported by default, | ||
so nothing extra needs to be done for callbacks to be invoked. | ||
|
||
If the `RINGBUF_FLAG_NO_AUTO_CALLBACK` flag is set, callbacks will not automatically be called and `ring_buffer__poll()` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should the default be different between Windows vs Linux?
Why not a RINGBUF_FLAG_AUTO_CALLBACK
flag instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To maintain current default behavior for existing ebpf-for-windows customers.
docs/RingBuffer.md
Outdated
* | ||
*/ | ||
ebpf_result_t | ||
ebpf_ring_buffer_output(ebpf_ring_buffer_t* ring, uint8_t* data, size_t length, size_t flags) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add SAL annotations to ebpf_* APIs in this doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added them to all the functions (for clarity), though they'll only be in the ebpf_* functions in the implementation of this proposal.
docs/RingBuffer.md
Outdated
size_t sz; /* size of this struct, for forward/backward compatiblity */ | ||
uint64_t flags; /* ring buffer option flags */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix indentation so these lines match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
docs/RingBuffer.md
Outdated
* | ||
* @returns Pointer to consumer offset | ||
*/ | ||
uint64_t* rb__consumer_offset(void *cons); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this exact same prototype exist on Linux? I couldn't find it, I could only find
https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h#L4558 as a helper function.
This doesn't follow https://github.com/microsoft/ebpf-for-windows/blob/main/docs/DevelopmentGuide.md#coding-conventions so is only ok if it's identical to Linux.
docs/RingBuffer.md
Outdated
* | ||
* @returns Pointer to producer offset | ||
*/ | ||
volatile const uint64_t* rb__producer_offset(volatile const void *prod); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this exact same prototype exist on Linux? I couldn't find it, I could only find
https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h#L4558
// consumer code | ||
struct ring_buffer_opts opts; | ||
opts.sz = sizeof(opts); | ||
opts.flags = RINGBUF_FLAG_NO_AUTO_CALLBACK; //no automatic callbacks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One should not need to opt into Linux behavior, it should be the default.
We want to avoid gratuitous differences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it is not optimal, but the reason for this is avoid a compatibility break for existing ebpf-for-windows customers.
Description
Add docs/RingBuffer.md with proposal for new ebpf ring buffer map API exposing mapped memory so consumers can directly read the records written by the producer (similar to linux mmap/epoll style ring buffer consumer).
Testing
N/A
Documentation
Documentation only.
Installation
N/A