Commit ef3b8200 authored by Martin Kelly's avatar Martin Kelly Committed by Andrii Nakryiko

libbpf: Switch rings to array of pointers

Switch rb->rings to be an array of pointers instead of a contiguous
block. This allows for each ring pointer to be stable after
ring_buffer__add is called, which allows us to expose struct ring * to
the user without gotchas. Without this change, the realloc in
ring_buffer__add could invalidate a struct ring *, making it unsafe to
give to the user.
Signed-off-by: default avatarMartin Kelly <martin.kelly@crowdstrike.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20230925215045.2375758-3-martin.kelly@crowdstrike.com
parent 4448f64c
...@@ -34,7 +34,7 @@ struct ring { ...@@ -34,7 +34,7 @@ struct ring {
struct ring_buffer { struct ring_buffer {
struct epoll_event *events; struct epoll_event *events;
struct ring *rings; struct ring **rings;
size_t page_size; size_t page_size;
int epoll_fd; int epoll_fd;
int ring_cnt; int ring_cnt;
...@@ -57,7 +57,7 @@ struct ringbuf_hdr { ...@@ -57,7 +57,7 @@ struct ringbuf_hdr {
__u32 pad; __u32 pad;
}; };
static void ringbuf_unmap_ring(struct ring_buffer *rb, struct ring *r) static void ringbuf_free_ring(struct ring_buffer *rb, struct ring *r)
{ {
if (r->consumer_pos) { if (r->consumer_pos) {
munmap(r->consumer_pos, rb->page_size); munmap(r->consumer_pos, rb->page_size);
...@@ -67,6 +67,8 @@ static void ringbuf_unmap_ring(struct ring_buffer *rb, struct ring *r) ...@@ -67,6 +67,8 @@ static void ringbuf_unmap_ring(struct ring_buffer *rb, struct ring *r)
munmap(r->producer_pos, rb->page_size + 2 * (r->mask + 1)); munmap(r->producer_pos, rb->page_size + 2 * (r->mask + 1));
r->producer_pos = NULL; r->producer_pos = NULL;
} }
free(r);
} }
/* Add extra RINGBUF maps to this ring buffer manager */ /* Add extra RINGBUF maps to this ring buffer manager */
...@@ -107,8 +109,10 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd, ...@@ -107,8 +109,10 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
return libbpf_err(-ENOMEM); return libbpf_err(-ENOMEM);
rb->events = tmp; rb->events = tmp;
r = &rb->rings[rb->ring_cnt]; r = calloc(1, sizeof(*r));
memset(r, 0, sizeof(*r)); if (!r)
return libbpf_err(-ENOMEM);
rb->rings[rb->ring_cnt] = r;
r->map_fd = map_fd; r->map_fd = map_fd;
r->sample_cb = sample_cb; r->sample_cb = sample_cb;
...@@ -161,7 +165,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd, ...@@ -161,7 +165,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
return 0; return 0;
err_out: err_out:
ringbuf_unmap_ring(rb, r); ringbuf_free_ring(rb, r);
return libbpf_err(err); return libbpf_err(err);
} }
...@@ -173,7 +177,7 @@ void ring_buffer__free(struct ring_buffer *rb) ...@@ -173,7 +177,7 @@ void ring_buffer__free(struct ring_buffer *rb)
return; return;
for (i = 0; i < rb->ring_cnt; ++i) for (i = 0; i < rb->ring_cnt; ++i)
ringbuf_unmap_ring(rb, &rb->rings[i]); ringbuf_free_ring(rb, rb->rings[i]);
if (rb->epoll_fd >= 0) if (rb->epoll_fd >= 0)
close(rb->epoll_fd); close(rb->epoll_fd);
...@@ -281,7 +285,7 @@ int ring_buffer__consume(struct ring_buffer *rb) ...@@ -281,7 +285,7 @@ int ring_buffer__consume(struct ring_buffer *rb)
int i; int i;
for (i = 0; i < rb->ring_cnt; i++) { for (i = 0; i < rb->ring_cnt; i++) {
struct ring *ring = &rb->rings[i]; struct ring *ring = rb->rings[i];
err = ringbuf_process_ring(ring); err = ringbuf_process_ring(ring);
if (err < 0) if (err < 0)
...@@ -308,7 +312,7 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms) ...@@ -308,7 +312,7 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
__u32 ring_id = rb->events[i].data.fd; __u32 ring_id = rb->events[i].data.fd;
struct ring *ring = &rb->rings[ring_id]; struct ring *ring = rb->rings[ring_id];
err = ringbuf_process_ring(ring); err = ringbuf_process_ring(ring);
if (err < 0) if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment