• David Vernet's avatar
    bpf: Add bpf_user_ringbuf_drain() helper · 20571567
    David Vernet authored
    In a prior change, we added a new BPF_MAP_TYPE_USER_RINGBUF map type which
    will allow user-space applications to publish messages to a ring buffer
    that is consumed by a BPF program in kernel-space. In order for this
    map-type to be useful, it will require a BPF helper function that BPF
    programs can invoke to drain samples from the ring buffer, and invoke
    callbacks on those samples. This change adds that capability via a new BPF
    helper function:
    
    bpf_user_ringbuf_drain(struct bpf_map *map, void *callback_fn, void *ctx,
                           u64 flags)
    
    BPF programs may invoke this function to run callback_fn() on a series of
    samples in the ring buffer. callback_fn() has the following signature:
    
    long callback_fn(struct bpf_dynptr *dynptr, void *context);
    
    Samples are provided to the callback in the form of struct bpf_dynptr *'s,
    which the program can read using BPF helper functions for querying
    struct bpf_dynptr's.
    
    In order to support bpf_ringbuf_drain(), a new PTR_TO_DYNPTR register
    type is added to the verifier to reflect a dynptr that was allocated by
    a helper function and passed to a BPF program. Unlike PTR_TO_STACK
    dynptrs which are allocated on the stack by a BPF program, PTR_TO_DYNPTR
    dynptrs need not use reference tracking, as the BPF helper is trusted to
    properly free the dynptr before returning. The verifier currently only
    supports PTR_TO_DYNPTR registers that are also DYNPTR_TYPE_LOCAL.
    
    Note that while the corresponding user-space libbpf logic will be added
    in a subsequent patch, this patch does contain an implementation of the
    .map_poll() callback for BPF_MAP_TYPE_USER_RINGBUF maps. This
    .map_poll() callback guarantees that an epoll-waiting user-space
    producer will receive at least one event notification whenever at least
    one sample is drained in an invocation of bpf_user_ringbuf_drain(),
    provided that the function is not invoked with the BPF_RB_NO_WAKEUP
    flag. If the BPF_RB_FORCE_WAKEUP flag is provided, a wakeup
    notification is sent even if no sample was drained.
    Signed-off-by: default avatarDavid Vernet <void@manifault.com>
    Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Link: https://lore.kernel.org/bpf/20220920000100.477320-3-void@manifault.com
    20571567
ringbuf.c 21.8 KB