• Andrii Nakryiko's avatar
    libbpf: Wire up USDT API and bpf_link integration · 2e4913e0
    Andrii Nakryiko authored
    Wire up libbpf USDT support APIs without yet implementing all the
    nitty-gritty details of USDT discovery, spec parsing, and BPF map
    initialization.
    
    User-visible user-space API is simple and is conceptually very similar
    to uprobe API.
    
    bpf_program__attach_usdt() API allows to programmatically attach given
    BPF program to a USDT, specified through binary path (executable or
    shared lib), USDT provider and name. Also, just like in uprobe case, PID
    filter is specified (0 - self, -1 - any process, or specific PID).
    Optionally, USDT cookie value can be specified. Such single API
    invocation will try to discover given USDT in specified binary and will
    use (potentially many) BPF uprobes to attach this program in correct
    locations.
    
    Just like any bpf_program__attach_xxx() APIs, bpf_link is returned that
    represents this attachment. It is a virtual BPF link that doesn't have
    direct kernel object, as it can consist of multiple underlying BPF
    uprobe links. As such, attachment is not atomic operation and there can
    be brief moment when some USDT call sites are attached while others are
    still in the process of attaching. This should be taken into
    consideration by user. But bpf_program__attach_usdt() guarantees that
    in the case of success all USDT call sites are successfully attached, or
    all the successfuly attachments will be detached as soon as some USDT
    call sites failed to be attached. So, in theory, there could be cases of
    failed bpf_program__attach_usdt() call which did trigger few USDT
    program invocations. This is unavoidable due to multi-uprobe nature of
    USDT and has to be handled by user, if it's important to create an
    illusion of atomicity.
    
    USDT BPF programs themselves are marked in BPF source code as either
    SEC("usdt"), in which case they won't be auto-attached through
    skeleton's <skel>__attach() method, or it can have a full definition,
    which follows the spirit of fully-specified uprobes:
    SEC("usdt/<path>:<provider>:<name>"). In the latter case skeleton's
    attach method will attempt auto-attachment. Similarly, generic
    bpf_program__attach() will have enought information to go off of for
    parameterless attachment.
    
    USDT BPF programs are actually uprobes, and as such for kernel they are
    marked as BPF_PROG_TYPE_KPROBE.
    
    Another part of this patch is USDT-related feature probing:
      - BPF cookie support detection from user-space;
      - detection of kernel support for auto-refcounting of USDT semaphore.
    
    The latter is optional. If kernel doesn't support such feature and USDT
    doesn't rely on USDT semaphores, no error is returned. But if libbpf
    detects that USDT requires setting semaphores and kernel doesn't support
    this, libbpf errors out with explicit pr_warn() message. Libbpf doesn't
    support poking process's memory directly to increment semaphore value,
    like BCC does on legacy kernels, due to inherent raciness and danger of
    such process memory manipulation. Libbpf let's kernel take care of this
    properly or gives up.
    
    Logistically, all the extra USDT-related infrastructure of libbpf is put
    into a separate usdt.c file and abstracted behind struct usdt_manager.
    Each bpf_object has lazily-initialized usdt_manager pointer, which is
    only instantiated if USDT programs are attempted to be attached. Closing
    BPF object frees up usdt_manager resources. usdt_manager keeps track of
    USDT spec ID assignment and few other small things.
    
    Subsequent patches will fill out remaining missing pieces of USDT
    initialization and setup logic.
    Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Reviewed-by: default avatarAlan Maguire <alan.maguire@oracle.com>
    Link: https://lore.kernel.org/bpf/20220404234202.331384-3-andrii@kernel.org
    2e4913e0
libbpf.c 332 KB