Hi David, On Mon, Aug 8, 2022 at 8:52 AM David Vernet <void@xxxxxxxxxxxxx> wrote: > > This patch set defines a new map type, BPF_MAP_TYPE_USER_RINGBUF, which > provides single-user-space-producer / single-kernel-consumer semantics over > a ringbuffer. Along with the new map type, a helper function called > bpf_user_ringbuf_drain() is added which allows a BPF program to specify a > callback with the following signature, to which samples are posted by the > helper: > > void (struct bpf_dynptr *dynptr, void *context); > > The program can then use the bpf_dynptr_read() or bpf_dynptr_data() helper > functions to safely read the sample from the dynptr. There are currently no > helpers available to determine the size of the sample, but one could easily > be added if required. > > On the user-space side, libbpf has been updated to export a new > 'struct ring_buffer_user' type, along with the following symbols: > > struct ring_buffer_user * > ring_buffer_user__new(int map_fd, > const struct ring_buffer_user_opts *opts); > void ring_buffer_user__free(struct ring_buffer_user *rb); > void *ring_buffer_user__reserve(struct ring_buffer_user *rb, uint32_t size); > void *ring_buffer_user__poll(struct ring_buffer_user *rb, uint32_t size, > int timeout_ms); > void ring_buffer_user__discard(struct ring_buffer_user *rb, void *sample); > void ring_buffer_user__submit(struct ring_buffer_user *rb, void *sample); > > These symbols are exported for inclusion in libbpf version 1.0.0. > > Note that one thing that is not included in this patch-set is the ability > to kick the kernel from user-space to have it drain messages. The selftests > included in this patch-set currently just use progs with syscall hooks to > "kick" the kernel and have it drain samples from a user-producer > ringbuffer, but being able to kick the kernel using some other mechanism > that doesn't rely on such hooks would be very useful as well. I'm planning > on adding this in a future patch-set. > This could be done using iters. Basically, you can perform draining in bpf_iter programs and export iter links as bpffs files. Then to kick the kernel, you simply just read() the file. > Signed-off-by: David Vernet <void@xxxxxxxxxxxxx> > -- > > David Vernet (5): > bpf: Clear callee saved regs after updating REG0 > bpf: Define new BPF_MAP_TYPE_USER_RINGBUF map type > bpf: Add bpf_user_ringbuf_drain() helper > bpf: Add libbpf logic for user-space ring buffer > selftests/bpf: Add selftests validating the user ringbuf > > include/linux/bpf.h | 6 +- > include/linux/bpf_types.h | 1 + > include/uapi/linux/bpf.h | 9 + > kernel/bpf/helpers.c | 2 + > kernel/bpf/ringbuf.c | 232 ++++++- > kernel/bpf/verifier.c | 73 ++- > tools/include/uapi/linux/bpf.h | 9 + > tools/lib/bpf/libbpf.c | 11 +- > tools/lib/bpf/libbpf.h | 19 + > tools/lib/bpf/libbpf.map | 6 + > tools/lib/bpf/libbpf_probes.c | 1 + > tools/lib/bpf/ringbuf.c | 214 +++++++ > .../selftests/bpf/prog_tests/user_ringbuf.c | 592 ++++++++++++++++++ > .../selftests/bpf/progs/user_ringbuf_fail.c | 174 +++++ > .../bpf/progs/user_ringbuf_success.c | 227 +++++++ > .../testing/selftests/bpf/test_user_ringbuf.h | 28 + > 16 files changed, 1579 insertions(+), 25 deletions(-) > create mode 100644 tools/testing/selftests/bpf/prog_tests/user_ringbuf.c > create mode 100644 tools/testing/selftests/bpf/progs/user_ringbuf_fail.c > create mode 100644 tools/testing/selftests/bpf/progs/user_ringbuf_success.c > create mode 100644 tools/testing/selftests/bpf/test_user_ringbuf.h > > -- > 2.30.2 >