mirror of
https://github.com/netdata/libbpf.git
synced 2026-04-04 23:59:07 +08:00
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: Martin Kelly <martin.kelly@crowdstrike.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20230925215045.2375758-3-martin.kelly@crowdstrike.com
This commit is contained in:
committed by
Andrii Nakryiko
parent
64f2b4ab49
commit
bfa471bc85
@@ -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 {
|
|||||||
__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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user