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 15 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 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 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
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 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?

## 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?

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?

Comment on lines +56 to +57
* - 0 (auto/default): Notify if consumer has caught up.
* - BPF_RB_FORCE_WAKEUP - Always notify consumer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Inconsistent use of punctuation (: vs -)

*
*/
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.

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

* @param[out] producer pointer* to start of read-only mapped producer pages
* @param[out] consumer pointer* to start of read-write mapped consumer page
*
* @returns EBPF_SUCCESS on success, or error
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use retval rather than returns, e.g.

Suggested change
* @returns EBPF_SUCCESS on success, or error
* @retval EBPF_SUCCESS The operation was successful.
* @retval other An error occurred.

ebpf_result_t ebpf_ring_buffer_get_buffer(fd_t map_fd, void **producer, void **consumer);

/**
* get the wait handle to use with WaitForSingleObject/WaitForMultipleObject
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
* get the wait handle to use with WaitForSingleObject/WaitForMultipleObject
* Get the wait handle to use with WaitForSingleObject/WaitForMultipleObject.

*
* @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.

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