From: Teng Qin Date: Fri, 9 Dec 2016 08:07:55 +0000 (-0800) Subject: Improve C++ API perf buffer polling X-Git-Tag: v0.3.0~107^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cae072aeaeabf79100a33e593a2c6057909baa60;p=platform%2Fupstream%2Fbcc.git Improve C++ API perf buffer polling --- diff --git a/examples/cpp/RandomRead.cc b/examples/cpp/RandomRead.cc index e0c39aa..b39d960 100644 --- a/examples/cpp/RandomRead.cc +++ b/examples/cpp/RandomRead.cc @@ -30,6 +30,7 @@ struct urandom_read_args { struct event_t { int pid; char comm[16]; + int cpu; int got_bits; }; @@ -39,6 +40,7 @@ int on_urandom_read(struct urandom_read_args* attr) { struct event_t event = {}; event.pid = bpf_get_current_pid_tgid(); bpf_get_current_comm(&event.comm, sizeof(event.comm)); + event.cpu = bpf_get_smp_processor_id(); event.got_bits = attr->got_bits; events.perf_submit(attr, &event, sizeof(event)); @@ -50,13 +52,15 @@ int on_urandom_read(struct urandom_read_args* attr) { struct event_t { int pid; char comm[16]; + int cpu; int got_bits; }; void handle_output(void* cb_cookie, void* data, int data_size) { auto event = static_cast(data); - std::cout << "PID: " << event->pid << " (" << event->comm << ") " - << "Read " << event->got_bits << " bits" << std::endl; + std::cout << "PID: " << event->pid << " (" << event->comm << ") on CPU " + << event->cpu << " read " << event->got_bits << " bits" + << std::endl; } ebpf::BPF* bpf; diff --git a/src/cc/BPF.cc b/src/cc/BPF.cc index 7884f18..cc15f29 100644 --- a/src/cc/BPF.cc +++ b/src/cc/BPF.cc @@ -98,7 +98,7 @@ StatusTuple BPF::detach_all() { } for (auto it : perf_buffers_) { - auto res = it.second->close(); + auto res = it.second->close_all_cpu(); if (res.code() != 0) { error_msg += "Failed to close perf buffer " + it.first + ": "; error_msg += res.msg() + "\n"; @@ -279,7 +279,7 @@ StatusTuple BPF::open_perf_buffer(const std::string& name, if (perf_buffers_.find(name) == perf_buffers_.end()) perf_buffers_[name] = new BPFPerfBuffer(bpf_module_.get(), name); auto table = perf_buffers_[name]; - TRY2(table->open(cb, cb_cookie)); + TRY2(table->open_all_cpu(cb, cb_cookie)); return StatusTuple(0); } @@ -287,7 +287,7 @@ StatusTuple BPF::close_perf_buffer(const std::string& name) { auto it = perf_buffers_.find(name); if (it == perf_buffers_.end()) return StatusTuple(-1, "Perf buffer for %s not open", name.c_str()); - TRY2(it->second->close()); + TRY2(it->second->close_all_cpu()); return StatusTuple(0); } diff --git a/src/cc/BPFTable.cc b/src/cc/BPFTable.cc index c86718c..994e51f 100644 --- a/src/cc/BPFTable.cc +++ b/src/cc/BPFTable.cc @@ -79,13 +79,23 @@ StatusTuple BPFPerfBuffer::open_on_cpu(perf_reader_raw_cb cb, int cpu, return StatusTuple(-1, "Unable to open perf buffer on CPU %d: %s", cpu, strerror(errno)); } - cpu_readers_[cpu] = static_cast(reader); + cpu_readers_[cpu] = reader; + readers_.push_back(reader); return StatusTuple(0); } -StatusTuple BPFPerfBuffer::open(perf_reader_raw_cb cb, void* cb_cookie) { - for (int i = 0; i < sysconf(_SC_NPROCESSORS_ONLN); i++) - TRY2(open_on_cpu(cb, i, cb_cookie)); +StatusTuple BPFPerfBuffer::open_all_cpu(perf_reader_raw_cb cb, + void* cb_cookie) { + if (cpu_readers_.size() != 0 || readers_.size() != 0) + return StatusTuple(-1, "Previously opened perf buffer not cleaned"); + + for (int i = 0; i < sysconf(_SC_NPROCESSORS_ONLN); i++) { + auto res = open_on_cpu(cb, i, cb_cookie); + if (res.code() != 0) { + TRY2(close_all_cpu()); + return res; + } + } return StatusTuple(0); } @@ -100,7 +110,7 @@ StatusTuple BPFPerfBuffer::close_on_cpu(int cpu) { return StatusTuple(0); } -StatusTuple BPFPerfBuffer::close() { +StatusTuple BPFPerfBuffer::close_all_cpu() { std::string errors; bool has_error = false; for (int i = 0; i < sysconf(_SC_NPROCESSORS_ONLN); i++) { @@ -111,21 +121,20 @@ StatusTuple BPFPerfBuffer::close() { has_error = true; } } + readers_.clear(); if (has_error) return StatusTuple(-1, errors); return StatusTuple(0); } void BPFPerfBuffer::poll(int timeout) { - perf_reader* readers[cpu_readers_.size()]; - int i = 0; - for (auto it : cpu_readers_) - readers[i++] = it.second; - perf_reader_poll(cpu_readers_.size(), readers, timeout); + if (readers_.empty()) + return; + perf_reader_poll(readers_.size(), readers_.data(), timeout); } BPFPerfBuffer::~BPFPerfBuffer() { - auto res = close(); + auto res = close_all_cpu(); if (res.code() != 0) std::cerr << "Failed to close all perf buffer on destruction: " << res.msg() << std::endl; diff --git a/src/cc/BPFTable.h b/src/cc/BPFTable.h index 45743a0..c5f805d 100644 --- a/src/cc/BPFTable.h +++ b/src/cc/BPFTable.h @@ -126,8 +126,8 @@ public: : BPFTableBase(bpf_module, name) {} ~BPFPerfBuffer(); - StatusTuple open(perf_reader_raw_cb cb, void* cb_cookie); - StatusTuple close(); + StatusTuple open_all_cpu(perf_reader_raw_cb cb, void* cb_cookie); + StatusTuple close_all_cpu(); void poll(int timeout); private: @@ -135,6 +135,7 @@ private: StatusTuple close_on_cpu(int cpu); std::map cpu_readers_; + std::vector readers_; }; } // namespace ebpf