Re: [PATCH] libbpf: ringbuf: allow to partially consume items

From: Andrii Nakryiko
Date: Mon Mar 11 2024 - 13:56:20 EST


On Sun, Mar 10, 2024 at 8:47 AM Andrea Righi <andrea.righi@xxxxxxxxxxxxx> wrote:
>
> Instead of always consuming all items from a ring buffer in a greedy
> way, allow to stop when the callback returns a value > 0.
>
> This allows to distinguish between an error condition and an intentional
> stop condition by returning a non-negative non-zero value from the ring
> buffer callback.
>
> This can be useful, for example, to consume just a single item from the
> ring buffer.
>
> Signed-off-by: Andrea Righi <andrea.righi@xxxxxxxxxxxxx>
> ---
> tools/lib/bpf/ringbuf.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c
> index aacb64278a01..dd8908eb3204 100644
> --- a/tools/lib/bpf/ringbuf.c
> +++ b/tools/lib/bpf/ringbuf.c
> @@ -265,6 +265,14 @@ static int64_t ringbuf_process_ring(struct ring *r)
> return err;
> }
> cnt++;
> + if (err > 0) {

So libbpf already stops at any err < 0 (and sets correct consumer
pos). So you could already get desired behavior by just returning your
own error code. If you need count, you'd have to count it yourself
through custom context, that's a bit of inconvenience.

But on the other hand, currently if user callback returns anything > 0
they keep going and that return value is ignored. Your change will
break any such user pretty badly. So I'm a bit hesitant to do this.

Is there any reason you can't just return error code (libbpf doesn't
do anything with it, just passes it back, so it might as well be
`-cnt`, if you need that).

pw-bot: cr

> + /* update consumer pos and return the
> + * total amount of items consumed.
> + */
> + smp_store_release(r->consumer_pos,
> + cons_pos);
> + goto done;
> + }
> }
>
> smp_store_release(r->consumer_pos, cons_pos);
> --
> 2.43.0
>
>