-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Ringbuf Support for Python API #2989
Conversation
[buildbot, test this please] |
Is there an easy way to see what tests specifically are failing? Seems to be something in |
Probably a flaky test. Let me try again. |
[buildbot, test this please] |
Ah seems like it was indeed a flaky test. |
Thank you for your comments @anakryiko. I left a few followup questions / concerns as replies. I should have time to update this PR later today or tomorrow. |
@anakryiko I have now addressed all of your feedback (with the exception of pages vs bytes in the ringbuf macro, as discussed). Things seem to be in a good place now, but if you have any other concerns let me know. |
- Add rewriter support for map.ringbuf_output - Create abstract EventArrayBase to reduce code duplication between PerfEventArray and RingBuf in Python API
@yonghong-song Should be good to test again. I've added unit tests under tests/python/test_ringbuf.py, as well as examples and documentation. |
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.
It looks good from API perspective, would be good to get a review from someone more familiar with BCC internals, though. See also the point of being able to size ringbuf from user-space.
|
||
Syntax: ```table.open_ring_buffer(callback, ctx=None)``` | ||
|
||
This operates on a table as defined in BPF as BPF_RINGBUF_OUTPUT(), and associates the callback Python function ```callback``` to be called when data is available in the ringbuf ring buffer. This is part of the new (Linux 5.8+) recommended mechanism for transferring per-event data from kernel to user space. Unlike perf buffers, ringbuf sizes are specified within the BPF program, as part of the ```BPF_RINGBUF_OUTPUT``` macro. If the callback is not processing data fast enough, some submitted data may be lost. In this case, the events should be polled more frequently and/or the size of the ring buffer should be increased. |
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.
is there a way to set ringbuf size from Python API in user-space? There are probably cases, where this size is determined dynamically by user space logic
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 don't think this would be easy to implement given the way bcc treats maps. We could potentially change this in the future, but for now, I think the current API is fine. For now, if the user desires different map sizes according to userspace logic, they can just programmatically generate the correct C code. This is already a common pattern in bcc tools.
|
||
try: | ||
while 1: | ||
b.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.
ring_buffer_consume is very specialized use-case, I'd do all the examples with ring_buffer_poll() and just mention ring_buffer_consume as an alternative, as you did in the example above.
@yonghong-song, do you squash all those 44 commits into one when you land? I wonder if it makes sense to ask people to re-organize and squash into fewer logic commits before landing. E.g., implementation, testing and documentation commits. 44 commits are pretty unwieldy. |
@anakryiko Thanks for review. I won't push these 44 commits. I indeed frequently squash them into one commit. llvm sometimes also has giant commits. I think it is okay not to put burden on the developer for already done work. |
[buildbot, test this please] |
1 similar comment
[buildbot, test this please] |
Merged. Thanks @willfindlay and @anakryiko! |
The merge request [iovisor#2989] add include <asm/page.h> in src/cc/export/helper.h for new feature in Linux 5.7, but it will cause compiling bpf program failed, since it tried to include assembly code in header file. Temporally comment out this include, maybe need to check how to fix this issue in the future.
Hello First, thank you @willfindlay for this work. I have one question, in TC and XDP programs, how can we send the network packet to the user space program. Using perf buffers, this was possible by using the I'm trying to include an In the BCC reference guide and by browsing the libbpf library, I saw that when opening a ring buffer, there is a Could you provide help please? Regards |
This pull request contains an implementation for ringbuf support in bcc's Python API. Fixes iovisor#2985. More specifically, the following are added: - ringbuf helpers from libbpf API to libbcc - a new RingBuf class to represent the ringbuf map - BPF_RINGBUF_OUTPUT macro for BPF programs - tests - detailed documentation and examples
This pull request contains an implementation for ringbuf support in bcc's Python API.
Fixes #2985.
Summary of Changes
RingBuf
class to represent the ringbuf mapEventArrayBase
class to reduce code duplication between PerfEventArray and RingBufBPF_RINGBUF_OUTPUT
macro for BPF programsExamples
The following example programs describe how the API works.
On the BPF side, we have two choices for submitting events.
map.ringbuf_output
works likemap.perf_submit
for perf buffers,while
map.ringbuf_reserve
/map.ringbuf_discard
/map.ringbuf_submit
present an alternative approach that allows for finer control.map.ringbuf_output
works like:map.ringbuf_reserve
/map.ringbuf_discard
/map.ringbuf_submit
work like:On the Python side, the user calls
open_ring_buffer
to associate a callback with the buffer. There are two options for reading data from kernelspace:ring_buffer_poll
which works likeperf_buffer_poll
andring_buffer_consume
which reads data without polling first.Unlike perf buffer callbacks, ringbuf supports return values from the callback, which can be used to indicate error conditions to stop polling early. If a callback does not return an integer, we fall back to returning 0, which approximates perf buffer behavior.