aya-rs / aya

Aya is an eBPF library for the Rust programming language, built with a focus on developer experience and operability.
https://aya-rs.dev/book/
Apache License 2.0
3.25k stars 291 forks source link

[bug] Userspace never receives events on a `PerfEventArray` if the element size is >= 8176 bytes #1015

Open dljsjr opened 3 months ago

dljsjr commented 3 months ago

Description

When submitting a bpf_perf_output using PerfEventArray::output(&self, ...) from the attached eBPF Program, the userspace side's array never returns true for readable if the array element type has a size >= 8176 bytes. I checked this both under tokio and using the blocking API.

It's possible this is just a limitation of PerfEventArrays, but I wasn't able to find anything in the bpf documentation that outlines this; I was looking for something like the docs on the PerCpuArray, which mentions the 32KB size limit. I didn't find anything. So apologies if this is a limitation and not a bug. But the verifier doesn't complain, there is no crash, the eBPF program continues to run on every packet; if I add a print after the output call, it prints. So it seems like the kernel and the VM are happy, I'm just never seeing anything in userspace.

Environment

Program type: kprobe

Feature Detection info:

[2024-08-23T17:46:50Z DEBUG aya::bpf] BPF Feature Detection: Features {
        bpf_name: true,
        bpf_probe_read_kernel: true,
        bpf_perf_link: true,
        bpf_global_data: true,
        bpf_cookie: true,
        cpumap_prog_id: true,
        devmap_prog_id: true,
        btf: Some(
            BtfFeatures {
                btf_func: true,
                btf_func_global: true,
                btf_datasec: true,
                btf_float: true,
                btf_decl_tag: false,
                btf_type_tag: false,
                btf_enum64: false,
            },
        ),
    }

Kernel: 5.15.0-119-generic

/boot/config-5.15.0-119-generic contents: config-5.15.0-119-generic.txt

Steps to reproduce

A reproduction repository based on the template can be found here: https://github.com/dljsjr/undump-aya

With the constant as defined here: https://github.com/dljsjr/undump-aya/blob/main/undump-aya-common/src/lib.rs#L8, everything works as expected.

Switching to this version of the constant a few lines down: https://github.com/dljsjr/undump-aya/blob/main/undump-aya-common/src/lib.rs#L11, no events are ever received by the userspace program.