On Sat Jun 13, 2026 at 9:48 PM EDT, Tamir Duberstein wrote:
> ringbuf_process_ring() checks the record bound only after advancing the
> consumer position and invoking the callback. A zero bound therefore
> consumes the first available record.
>
> Return before reading the ring positions when the bound is zero so
> ring_buffer__consume_n() and ring__consume_n() leave all records queued.
>
> Fixes: 4d22ea94ea33 ("libbpf: Add ring__consume_n / ring_buffer__consume_n")
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Tamir Duberstein <[email protected]>Reviewed-by: Emil Tsalapatis <[email protected]> > --- > tools/lib/bpf/ringbuf.c | 3 +++ > tools/testing/selftests/bpf/prog_tests/ringbuf.c | 13 +++++++++++++ > 2 files changed, 16 insertions(+) > > diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c > index 00ec4837a06d..f2bb619d5a75 100644 > --- a/tools/lib/bpf/ringbuf.c > +++ b/tools/lib/bpf/ringbuf.c > @@ -240,6 +240,9 @@ static int64_t ringbuf_process_ring(struct ring *r, > size_t n) > bool got_new_data; > void *sample; > > + if (n == 0) > + return 0; > + > cons_pos = smp_load_acquire(r->consumer_pos); > do { > got_new_data = false; > diff --git a/tools/testing/selftests/bpf/prog_tests/ringbuf.c > b/tools/testing/selftests/bpf/prog_tests/ringbuf.c > index 64520684d2cb..4f0558f14847 100644 > --- a/tools/testing/selftests/bpf/prog_tests/ringbuf.c > +++ b/tools/testing/selftests/bpf/prog_tests/ringbuf.c > @@ -404,6 +404,7 @@ static int process_n_sample(void *ctx, void *data, size_t > len) > static void ringbuf_n_subtest(void) > { > struct test_ringbuf_n_lskel *skel_n; > + struct ring *ring; > int err, i; > > skel_n = test_ringbuf_n_lskel__open(); > @@ -431,6 +432,18 @@ static void ringbuf_n_subtest(void) > for (i = 0; i < N_TOT_SAMPLES; i++) > syscall(__NR_getpgid); > > + ring = ring_buffer__ring(ringbuf, 0); > + if (!ASSERT_OK_PTR(ring, "ring_buffer__ring")) > + goto cleanup_ringbuf; > + > + err = ring_buffer__consume_n(ringbuf, 0); > + if (!ASSERT_EQ(err, 0, "ringbuf_consume_zero")) > + goto cleanup_ringbuf; > + > + err = ring__consume_n(ring, 0); > + if (!ASSERT_EQ(err, 0, "ring_consume_zero")) > + goto cleanup_ringbuf; > + > /* Consume all samples from the ring buffer in batches of N_SAMPLES */ > for (i = 0; i < N_TOT_SAMPLES; i += err) { > err = ring_buffer__consume_n(ringbuf, N_SAMPLES);

