Skip to content
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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

mikeagun
Copy link
Collaborator

@mikeagun mikeagun commented Sep 18, 2024

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

Alan-Jowett
Alan-Jowett previously approved these changes Sep 23, 2024
@mikeagun mikeagun changed the title New ringbuffer proposal Design proposal for new ring buffer API Sep 24, 2024
docs/RingBuffer.md Outdated Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
@mikeagun mikeagun marked this pull request as draft October 2, 2024 22:51
@mikeagun
Copy link
Collaborator Author

mikeagun commented Oct 2, 2024

Converting to draft while I make a few design updates.

@mikeagun mikeagun marked this pull request as ready for review October 3, 2024 19:03
docs/RingBuffer.md Outdated Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
matthewige
matthewige previously approved these changes Oct 9, 2024
docs/RingBuffer.md Outdated Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
Copy link
Member

@Alan-Jowett Alan-Jowett left a 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).

docs/RingBuffer.md Outdated Show resolved Hide resolved
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 Show resolved Hide resolved
shpalani
shpalani previously approved these changes Oct 26, 2024
docs/RingBuffer.md Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved

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()`.
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

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()`
Copy link
Collaborator

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?

Copy link
Collaborator Author

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 Show resolved Hide resolved
*
*/
ebpf_result_t
ebpf_ring_buffer_output(ebpf_ring_buffer_t* ring, uint8_t* data, size_t length, size_t flags)
Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

Comment on lines 79 to 80
size_t sz; /* size of this struct, for forward/backward compatiblity */
uint64_t flags; /* ring buffer option flags */
Copy link
Collaborator

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

Copy link
Collaborator Author

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 Show resolved Hide resolved
docs/RingBuffer.md Outdated Show resolved Hide resolved
*
* @returns Pointer to consumer offset
*/
uint64_t* rb__consumer_offset(void *cons);
Copy link
Collaborator

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.

*
* @returns Pointer to producer offset
*/
volatile const uint64_t* rb__producer_offset(volatile const void *prod);
Copy link
Collaborator

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
Copy link
Collaborator

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.

Copy link
Collaborator Author

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.

Michael Agun added 2 commits January 8, 2025 11:18
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.

7 participants