You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -14,15 +14,15 @@ This proposal adds support for synchronous callbacks (like libbpf on linux) and
14
14
15
15
Asynchronous callback consumer:
16
16
17
-
1. Call `ring_buffer__new` to set up callback with RINGBUF_FLAG_AUTO_CALLBACK specified.
18
-
- On Linux synchronous callbacks are always used, so the new AUTO_CALLBACK flags are Windows-specific.
19
-
- Note: automatic callbacks are the current default behavior, but eventually
20
-
this will change with [#4142](https://github.com/microsoft/ebpf-for-windows/issues/4142) to match the linux behavior so should always be specified.
17
+
1. Call `ebpf_ring_buffer__new` to set up callback with `EBPF_RINGBUF_FLAG_AUTO_CALLBACK` specified.
18
+
- On Linux synchronous callbacks are always used, so the `EBPF_RINGBUF_FLAG_AUTO_CALLBACK` flag is Windows-specific.
19
+
- Note: automatic callbacks were the original default behavior, but the default has been changed to be source-compatible with Linux.
21
20
2. The callback will be invoked for each record written to the ring buffer.
22
21
23
22
Synchronous callback consumer:
24
23
25
-
1. Call `ring_buffer__new` to set up callback with RINGBUF_FLAG_NO_AUTO_CALLBACK specified.
24
+
1. Call `ring_buffer__new` to set up callback (uses synchronous mode by default to match Linux).
25
+
- Or call `ebpf_ring_buffer__new` with `EBPF_RINGBUF_FLAG_NO_AUTO_CALLBACK` for explicit synchronous mode.
26
26
2. Call `ring_buffer__poll()` to wait for data if needed and invoke the callback on all available records.
27
27
28
28
Mapped memory consumer:
@@ -41,35 +41,28 @@ On linux `ring_buffer__poll()` and `ring_buffer__consume()` are used to invoke t
41
41
`poll()` waits for available data (or until timeout), then consume all available records.
42
42
`consume()` consumes all available records (without waiting).
43
43
44
-
Windows will initially only support `ring_buffer__poll()`, which can be called with a timeout of zero
45
-
to get the same behaviour as `ring_buffer__consume()`.
44
+
Windows now supports both `ring_buffer__poll()` and `ring_buffer__consume()`, with Linux-compatible behavior.
45
+
`ring_buffer__consume()` is equivalent to calling `ring_buffer__poll()` with a timeout of zero.
46
46
47
47
#### Asynchronous callbacks
48
48
49
-
On Linux ring buffers currently support only synchronous callbacks (using poll/consume).
50
-
In contrast, Windows eBPF currently supports only asynchronous ring buffer callbacks,
51
-
where the callback is automatically invoked when data is available.
49
+
On Linux ring buffers support only synchronous callbacks (using poll/consume).
50
+
Windows eBPF now supports both synchronous callbacks (default, matching Linux) and asynchronous ring buffer callbacks.
52
51
53
-
This proposal adds support for synchronous consumers by setting the `RINGBUF_FLAG_NO_AUTO_CALLBACK` flag.
54
-
With the flag set, callbacks will not automatically be called.
55
-
To invoke the callback and `ring_buffer__poll()`
56
-
should be called to poll for available data and invoke the callback.
57
-
On Windows a timeout of zero can be passed to `ring_buffer__poll()` to get the same behaviour as `ring_buffer__consume()` (consume available records without waiting).
58
-
59
-
When #4142 is resolved the default behaviour will be changed from asynchronous (automatic) to synchronous callbacks,
60
-
so `RINGBUF_FLAG_AUTO_CALLBACK` should always be specified for asynchronous callbacks for forward-compatibility.
52
+
For synchronous callbacks (Linux-compatible), use the default behavior with `ring_buffer__new()`.
53
+
For asynchronous callbacks (Windows-specific), use `ebpf_ring_buffer__new()` with the `EBPF_RINGBUF_FLAG_AUTO_CALLBACK` flag.
61
54
62
55
#### Memory mapped consumers
63
56
64
57
As an alternative to callbacks, Linux ring buffer consumers can directly access the
65
58
ring buffer data by calling `mmap()` on a ring_buffer map fd to map the data into user space.
66
59
`ring_buffer__epoll_fd()` is used on Linux to get an fd to use with epoll to wait for data.
67
60
68
-
Windows doesn't have directly compatible APIs to Linux mmap and epoll, so instead we will perfom the mapping
61
+
Windows doesn't have directly compatible APIs to Linux mmap and epoll, so instead we perform the mapping
69
62
in the eBPF core and use a KEVENT to signal for new data.
70
63
71
-
For direct memory mapped consumers on Windows, use `ebpf_ring_buffer_get_buffer` to get pointers to the producer and consumer
72
-
pages mapped into user space, and `ebpf_ring_buffer_get_wait_handle()` to get the SynchronizationEvent (auto-reset) KEVENT
64
+
For direct memory mapped consumers on Windows, use `ebpf_ring_buffer_map_map_buffer` to get pointers to the producer and consumer
65
+
pages mapped into user space, and `ebpf_map_set_wait_handle()` to set a HANDLE
73
66
to use with `WaitForSingleObject`/`WaitForMultipleObject`.
74
67
75
68
Similar to the linux memory layout, the first pages of the shared ring buffer memory are the "producer page" and "consumer page",
_Note:_ The currently internal `ebpf_ring_buffer_record.h` with helpers for working with raw records will also be made public.
93
+
**Note:** The currently internal `ebpf_ring_buffer_record.h` with helpers for working with raw records will also be made public.
101
94
102
95
#### Updated libbpf API for callback consumer
103
96
104
-
The default behaviour of these functions will be unchanged for now.
97
+
The default behaviour of these functions has been updated to use synchronous callbacks to match Linux libbpf behavior.
98
+
99
+
Use `ring_buffer__new()` (defaults to synchronous mode) or `ebpf_ring_buffer__new()` with `EBPF_RINGBUF_FLAG_AUTO_CALLBACK` to set up automatic callbacks for each record.
100
+
Use `ring_buffer__new()` (default behavior) or `ebpf_ring_buffer__new()` with `EBPF_RINGBUF_FLAG_NO_AUTO_CALLBACK` to set up synchronous callbacks that are invoked via `ring_buffer__poll()` or `ring_buffer__consume()`.
105
101
106
-
Use the existing `ring_buffer__new()` to set up automatic callbacks for each record.
0 commit comments