PERF & RING BUFFER
总述
BPF中,内核向用户空间发送数据使用的缓冲区称为PERF缓冲区;在Linux 5.8版本之后,可以使用环形缓冲区RING BUFFER(RB)
RING BUFFER优势
- 降低内存开销:PERF为每个CPU分配缓存;RB为所有CPU分配一个共享的大缓冲区
- “大缓冲区”一位置更好容忍数据毛刺
- 内存使用效率更高
- 内存拓展性更好,如CPU数量增加时,PERF的buffer跟着翻倍,而RB可能不需要新增那么多内存
- 保证事件顺序:由于per-CPU特性, 如果事件发生间隔非常短且分散在不同CPU中,事件的发送顺序就可能乱掉;RB由于共享同一个缓冲区,就不会有上述问题
- 减少数据复制:PERF必须先初始化一份事件数据,然后复制到perfbuf,之后发送到用户口空间,因此,数据会被复制两次;RB会首先为数据预留空间,预留成功后可以直接把发送的数据放到RB中,无需像PERF一样多一次将数据复制到局部变量中
PERF和RF主要结构对比
PERF:
struct perf_buffer {
perf_buffer_event_fn event_cb;
perf_buffer_sample_fn sample_cb;
perf_buffer_lost_fn lost_cb;
void *ctx; /* passed into callbacks */
size_t page_size;
size_t mmap_size;
struct perf_cpu_buf **cpu_bufs;
struct epoll_event *events;
int cpu_cnt; /* number of allocated CPU buffers */
int epoll_fd; /* perf event FD */
int map_fd; /* BPF_MAP_TYPE_PERF_EVENT_ARRAY BPF map FD */
};
RB:
struct ring_buffer {
struct epoll_event *events;
struct ring *rings;
size_t page_size;
int epoll_fd;
int ring_cnt;
};
例程
见该篇博客第三部分
发表评论