On Sat, Apr 6, 2024 at 2:20 AM Andrea Righi andrea.righi@canonical.com wrote:
In some cases, instead of always consuming all items from ring buffers in a greedy way, we may want to consume up to a certain amount of items, for example when we need to copy items from the BPF ring buffer to a limited user buffer.
This change allows to set an upper limit to the amount of items consumed from one or more ring buffers.
Signed-off-by: Andrea Righi andrea.righi@canonical.com
tools/lib/bpf/ringbuf.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c index aacb64278a01..2c4031168413 100644 --- a/tools/lib/bpf/ringbuf.c +++ b/tools/lib/bpf/ringbuf.c @@ -231,7 +231,7 @@ static inline int roundup_len(__u32 len) return (len + 7) / 8 * 8; }
-static int64_t ringbuf_process_ring(struct ring *r) +static int64_t ringbuf_process_ring(struct ring *r, size_t n) { int *len_ptr, len, err; /* 64-bit to avoid overflow in case of extreme application behavior */ @@ -268,6 +268,9 @@ static int64_t ringbuf_process_ring(struct ring *r) }
smp_store_release(r->consumer_pos, cons_pos);
if (cnt >= n)
goto done; } } while (got_new_data);
done: @@ -287,13 +290,15 @@ int ring_buffer__consume(struct ring_buffer *rb) for (i = 0; i < rb->ring_cnt; i++) { struct ring *ring = rb->rings[i];
err = ringbuf_process_ring(ring);
err = ringbuf_process_ring(ring, INT_MAX); if (err < 0) return libbpf_err(err); res += err;
if (res > INT_MAX) {
res = INT_MAX;
break;
} }
if (res > INT_MAX)
return INT_MAX;
the idea here was to avoid returning overflown int, not really to stop at INT_MAX samples. So I kept this part intact (res is int64_t, so no overflow inside the loop can happen)
return res;
}
@@ -314,13 +319,15 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms) __u32 ring_id = rb->events[i].data.fd; struct ring *ring = rb->rings[ring_id];
err = ringbuf_process_ring(ring);
err = ringbuf_process_ring(ring, INT_MAX); if (err < 0) return libbpf_err(err); res += err;
if (res > INT_MAX) {
res = INT_MAX;
break;
} }
if (res > INT_MAX)
return INT_MAX; return res;
}
@@ -375,7 +382,7 @@ int ring__consume(struct ring *r) { int64_t res;
res = ringbuf_process_ring(r);
res = ringbuf_process_ring(r, INT_MAX); if (res < 0) return libbpf_err(res);
-- 2.43.0