diff options
| author | Israel Téllez García <i.tellez@btesa.com> | 2026-08-14 14:48:43 +0200 |
|---|---|---|
| committer | Andrii Nakryiko <andrii@kernel.org> | 2026-08-14 15:21:09 -0700 |
| commit | fdd4fad0bbbd08501465c5f9b556963093c5d58a (patch) | |
| tree | 66cd0bdb23482f9645ac2b23ff407c28ac3ea982 /tools/perf/scripts/python/stackcollapse.py | |
| parent | 3f611e9b820ee0d01af89bb0643ccfac76cc569d (diff) | |
libbpf: Fix ring buffer consumer loop on 32-bit position wrap
ringbuf_process_ring() walks the records between the consumer and the
producer with an ordering comparison:
while (cons_pos < prod_pos) {
cons_pos and prod_pos mirror the kernel's ring positions and are
unsigned long here too, so on 32-bit they wrap at 2^32 bytes of traffic.
When producer_pos has wrapped and consumer_pos has not, prod_pos is the
smaller of the two, the loop body never runs and no record is consumed.
Since consumer_pos only advances inside that loop, it never wraps either
and the consumer stops delivering samples for good, with no error
returned to the caller: ring_buffer__poll() keeps reporting zero
records while the kernel side fills up and starts dropping.
Compare the distance instead. The consumer never runs ahead of the
producer, so prod_pos - cons_pos is the amount of unconsumed data and
stays correct across the wrap.
64-bit hosts are unaffected in practice: the counters would need 16 EiB
to wrap. This is the userspace counterpart of the kernel-side walk fixed
in "bpf: Fix pending_pos walk on 32-bit ring position wrap"; a 32-bit
consumer hits whichever of the two comes first.
Signed-off-by: Israel Téllez García <i.tellez@btesa.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260814124843.22041-5-i.tellez@btesa.com
Diffstat (limited to 'tools/perf/scripts/python/stackcollapse.py')
0 files changed, 0 insertions, 0 deletions
