diff options
| author | Israel Téllez García <i.tellez@btesa.com> | 2026-08-14 14:48:41 +0200 |
|---|---|---|
| committer | Andrii Nakryiko <andrii@kernel.org> | 2026-08-14 15:20:37 -0700 |
| commit | 3f611e9b820ee0d01af89bb0643ccfac76cc569d (patch) | |
| tree | cbda84bf983019655170a82214ebc9c2eb38128f /tools/perf/scripts/python/export-to-sqlite.py | |
| parent | 6ff5b56a50c5351aeeb180e34327736576c038fa (diff) | |
bpf: Fix available-data accounting on 32-bit wrap in overwrite mode
In overwrite mode ringbuf_avail_data_sz() picks the newer of the consumer
and overwrite positions before measuring how much data is available:
return prod_pos - max(cons_pos, over_pos);
max() is an ordering comparison, and consumer_pos, producer_pos and
overwrite_pos are unsigned long, i.e. 32-bit on 32-bit architectures,
where Documentation/bpf/ringbuf.rst allows them to wrap. Once one of the
two positions has wrapped and the other has not, max() returns the older
one: the result is then a modular difference close to 2^32, so the
function reports far more available data than the ring can hold. Pollers
using BPF_RB_AVAIL_DATA get a bogus figure, and epoll consumers can be
woken with nothing to read.
Compare distances rather than positions. prod_pos - X is the amount of
data produced since X for either position, wrap or no wrap, so the newer
position is simply the one with the smaller distance, which is also the
value the function wants to return.
64-bit hosts are unaffected in practice: their counters would need
16 EiB to wrap. Found by review of the same class of bug fixed in
"bpf: Fix pending_pos walk on 32-bit ring position wrap".
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-3-i.tellez@btesa.com
Diffstat (limited to 'tools/perf/scripts/python/export-to-sqlite.py')
0 files changed, 0 insertions, 0 deletions
