Re: [PATCH 0/5] bpf: Add user-space-publisher ringbuffer map type
From: Hao Luo
Date: Mon Aug 08 2022 - 14:58:23 EST
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
>