On Mon, Apr 1, 2024 at 12:32 AM Andrea Righi <andrea.righi@xxxxxxxxxxxxx> wrote: > > Introduce a new API to consume items from a ring buffer, limited to a > specified amount, and return to the caller the actual number of items > consumed. > > Link: https://lore.kernel.org/lkml/20240310154726.734289-1-andrea.righi@xxxxxxxxxxxxx/T > Signed-off-by: Andrea Righi <andrea.righi@xxxxxxxxxxxxx> > --- > tools/lib/bpf/libbpf.h | 13 +++++++++++++ > tools/lib/bpf/libbpf.map | 2 ++ > tools/lib/bpf/ringbuf.c | 35 +++++++++++++++++++++++++++++++++-- > 3 files changed, 48 insertions(+), 2 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > index f88ab50c0229..85161889efd4 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -1293,6 +1293,8 @@ LIBBPF_API int ring_buffer__add(struct ring_buffer *rb, int map_fd, > ring_buffer_sample_fn sample_cb, void *ctx); > LIBBPF_API int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms); > LIBBPF_API int ring_buffer__consume(struct ring_buffer *rb); > +LIBBPF_API int ring_buffer__consume_max(struct ring_buffer *rb, > + size_t max_items); > LIBBPF_API int ring_buffer__epoll_fd(const struct ring_buffer *rb); > > /** > @@ -1367,6 +1369,17 @@ LIBBPF_API int ring__map_fd(const struct ring *r); > */ > LIBBPF_API int ring__consume(struct ring *r); > > +/** > + * @brief **ring__consume_max()** consumes up to a certain amount of items from nit: certain -> requested ? > + * a ringbuffer without event polling. > + * > + * @param r A ringbuffer object. > + * @param max_items Maximum amount of items to consume. > + * @return The number of items consumed (or max_items, whichever is less), or a if we reach max_items, we did consume max_items, so I think "number of items consumed" is right and I'd drop the part in parenthesis > + * negative number if any of the callbacks return an error. > + */ > +LIBBPF_API int ring__consume_max(struct ring *r, size_t max_items); I'm bikeshedding here, of course, but I prefer `ring__consume_n` and max_items -> n. > + > struct user_ring_buffer_opts { > size_t sz; /* size of this struct, for forward/backward compatibility */ > }; > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index 51732ecb1385..bb3ed905119d 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -415,4 +415,6 @@ LIBBPF_1.4.0 { > bpf_token_create; > btf__new_split; > btf_ext__raw_data; > + ring__consume_max; > + ring_buffer__consume_max; we are in 1.5 cycle now, please add another section that inherits from LIBBPF_1.4.0 > } LIBBPF_1.3.0; > diff --git a/tools/lib/bpf/ringbuf.c b/tools/lib/bpf/ringbuf.c > index 81df535040d1..c8123e326b1a 100644 > --- a/tools/lib/bpf/ringbuf.c > +++ b/tools/lib/bpf/ringbuf.c > @@ -281,6 +281,32 @@ static int64_t ringbuf_process_ring(struct ring *r, int64_t max_items) > return cnt; > } > > +/* Consume available ring buffer(s) data without event polling up to max_items. > + * > + * Returns number of records consumed across all registered ring buffers (or > + * max_items, whichever is less), or negative number if any of the callbacks > + * return error. > + */ > +int ring_buffer__consume_max(struct ring_buffer *rb, size_t max_items) > +{ > + int64_t err, res = 0; > + int i; > + > + for (i = 0; i < rb->ring_cnt; i++) { > + struct ring *ring = rb->rings[i]; > + > + err = ringbuf_process_ring(ring, max_items); > + if (err < 0) > + return libbpf_err(err); > + res += err; > + max_items -= err; > + > + if (!max_items) please use `== 0`, it's not a bool and not a pointer > + break; > + } > + return res; > +} > + > /* Consume available ring buffer(s) data without event polling. > * Returns number of records consumed across all registered ring buffers (or > * INT_MAX, whichever is less), or negative number if any of the callbacks > @@ -376,17 +402,22 @@ int ring__map_fd(const struct ring *r) > return r->map_fd; > } > > -int ring__consume(struct ring *r) > +int ring__consume_max(struct ring *r, size_t max_items) > { > int64_t res; hm.. we can probably change this to int, can you do that as part of your changes? > > - res = ringbuf_process_ring(r, INT_MAX); > + res = ringbuf_process_ring(r, max_items); > if (res < 0) > return libbpf_err(res); > > return res; > } > > +int ring__consume(struct ring *r) > +{ > + return ring__consume_max(r, INT_MAX); > +} > + > static void user_ringbuf_unmap_ring(struct user_ring_buffer *rb) > { > if (rb->consumer_pos) { > -- > 2.43.0 >