From fc4d9a51e73938bbb6198334a2a9be93a9c22a74 Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Sun, 19 Oct 2025 04:06:35 +0530 Subject: [PATCH] Fix perf_buffer__new call --- src/core/bpf_perf_buffer.cpp | 59 +++++++++++++++++++----------------- src/core/bpf_perf_buffer.h | 3 +- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/core/bpf_perf_buffer.cpp b/src/core/bpf_perf_buffer.cpp index a1e7276..dceb747 100644 --- a/src/core/bpf_perf_buffer.cpp +++ b/src/core/bpf_perf_buffer.cpp @@ -1,6 +1,38 @@ #include "bpf_perf_buffer.h" #include "bpf_exception.h" +BpfPerfBuffer::BpfPerfBuffer(int map_fd, int page_cnt, py::function callback, + py::object lost_callback) + : pb_(nullptr), callback_(std::move(callback)), + lost_callback_(lost_callback) { + + if (page_cnt <= 0 || (page_cnt & (page_cnt - 1)) != 0) { + throw BpfException("page_cnt must be a positive power of 2"); + } + + struct perf_buffer_opts pb_opts = {}; + pb_opts.sz = sizeof(pb_opts); // Required for forward compatibility + + pb_ = perf_buffer__new( + map_fd, page_cnt, + sample_callback_wrapper, // sample_cb + lost_callback.is_none() ? nullptr : lost_callback_wrapper, // lost_cb + this, // ctx + &pb_opts // opts + ); + + if (!pb_) { + throw BpfException("Failed to create perf buffer: " + + std::string(std::strerror(errno))); + } +} + +BpfPerfBuffer::~BpfPerfBuffer() { + if (pb_) { + perf_buffer__free(pb_); + } +} + void BpfPerfBuffer::sample_callback_wrapper(void *ctx, int cpu, void *data, unsigned int size) { auto *self = static_cast(ctx); @@ -36,33 +68,6 @@ void BpfPerfBuffer::lost_callback_wrapper(void *ctx, int cpu, } } -BpfPerfBuffer::BpfPerfBuffer(int map_fd, int page_cnt, py::function callback, - py::object lost_callback) - : pb_(nullptr), callback_(std::move(callback)) { - - if (!lost_callback.is_none()) { - lost_callback_ = lost_callback.cast(); - } - - // Setup perf buffer options - perf_buffer_opts pb_opts = {}; - pb_opts.sample_cb = sample_callback_wrapper; - pb_opts.lost_cb = lost_callback.is_none() ? nullptr : lost_callback_wrapper; - pb_opts.ctx = this; - - // Create perf buffer - pb_ = perf_buffer__new(map_fd, page_cnt, &pb_opts); - if (!pb_) { - throw BpfException("Failed to create perf buffer"); - } -} - -BpfPerfBuffer::~BpfPerfBuffer() { - if (pb_) { - perf_buffer__free(pb_); - } -} - int BpfPerfBuffer::poll(int timeout_ms) { // Release GIL during blocking poll py::gil_scoped_release release; diff --git a/src/core/bpf_perf_buffer.h b/src/core/bpf_perf_buffer.h index 3794a2d..3f21213 100644 --- a/src/core/bpf_perf_buffer.h +++ b/src/core/bpf_perf_buffer.h @@ -20,11 +20,12 @@ private: public: BpfPerfBuffer(int map_fd, int page_cnt, py::function callback, - py::object lost_callback); + py::object lost_callback = py::none()); ~BpfPerfBuffer(); int poll(int timeout_ms); int consume(); + [[nodiscard]] int fd() const; }; #endif // PYLIBBPF_BPF_PERF_BUFFER_H