Linux5.8开始支持新的BPF数据结构(BPF map):BPF ring buffer(ringbug),它是一个多生产者、单消费者(MPSC)队列,可以同时在多个CPU之间安全地共享。在此之前,每当 BPF 程序需要将收集的数据发送到用户空间进行处理时,通常都会使用BPF perf buffer(perfbuf)。Perfbuf 是每个 CPU 循环缓冲区的集合,它允许在内核和用...
在编写了一个真实场景的高吞吐应用之后,我们证实了 ringbuf 在作为与 perfbuf 类似的 per-CPU buffer 使用时,仍然可以作为 perfbuf 的一个高性能替代品,尤其是用到手动管理事件通知(manual data availability notification)机制时。 BPF side user-space side 2.3 不可掩码中断(non-maskable interrupt)场景 唯一需要...
译者序 1 ringbuf 相比 perfbuf 的改进 1.1 降低内存开销(memory overhead) 1.2 保证事件顺序(event ordering) 1.3 减少数据复制(wasted data copy) 2 ringbuf 使用场景和性能 2.1 常规场景 2.2 高吞吐场景 2.3 不可掩码中断(non-maskable interrupt)场景 2.4 小结 3 示例程序(show me the code) 3.1 perfbuf...
译者序1 ringbuf 相比 perfbuf 的改进 1.1 降低内存开销(memory overhead) 1.2 保证事件顺序(event ordering) 1.3 减少数据复制(wasted data copy)2 ringbuf 使用场景和性能 2.1 常规场景 2.2 高吞吐场景 2.3 不可掩码中断(non-maskable interrupt)场景 2.4 小结3 示例程序(show me the code) 3.1 perfbuf 示...
(pb, 100 /* timeout, ms */);+ err = ring_buffer__poll(rb, 100 /* timeout, ms */);/* Ctrl-C will cause -EINTR */if (err == -EINTR) {err = 0;break;}if (err < 0) {- printf("Error polling perf buffer: %d\n", err);+ printf("Error polling ring buffer: %d\n", ...
If not, consumer still has to catch up and thus will see new data anyways without needing an extra poll notification. Benchmarks (see tools/testing/selftests/bpf/benchs/bench_ringbuf.c) show that this allows to achieve a very high throughput without having to resort to tricks like "notify...
BPF_MAP_TYPE_RINGBUF, BPF_MAP_TYPE_INODE_STORAGE, BPF_MAP_TYPE_TASK_STORAGE, }; 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
ring buffer polling 不需要序列化开销。bpf_buffer__poll API 将调用 handle_event 回调函数来处理环形缓冲区中的事件数据:static int handle_event(void *ctx, void *data, size_t data_sz) { const struct event *e = data; ... if (e->exit_event) { printf("%-8s %-5s %-16s %-7d %-7d ...
The callback function, process_sample, is called by ring_buffer__poll() or ring_buffer__consume() on each sample to “process” them according to user's needs. In this example, the callback only works on the data from the sample, printing a line which content depends on whether this ...
BPF_PERF_OUTPUT(output); BPF_RINGBUF_OUTPUT(output, 1); output.perf_submit(ctx, &data, sizeof(data)); output.ringbuf_output(&data, sizeof(data), 0); b["output"].open_perf_buffer(print_event) b["output"].open_ring_buffer(print_event) b.perf_buffer_poll() b.ring_buffer_poll(...