Commit 5cf87883 authored by Teng Qin's avatar Teng Qin

clang-format C++ API and example files

parent 15488d75
...@@ -83,10 +83,11 @@ int main(int argc, char** argv) { ...@@ -83,10 +83,11 @@ int main(int argc, char** argv) {
auto table_handle = bpf.get_hash_table<query_probe_t, int>("queries"); auto table_handle = bpf.get_hash_table<query_probe_t, int>("queries");
auto table = table_handle.get_table_offline(); auto table = table_handle.get_table_offline();
std::sort(table.begin(), table.end(), [](std::pair<query_probe_t, int> a, std::sort(
std::pair<query_probe_t, int> b) { table.begin(), table.end(),
return a.first.ts < b.first.ts; [](std::pair<query_probe_t, int> a, std::pair<query_probe_t, int> b) {
}); return a.first.ts < b.first.ts;
});
std::cout << table.size() << " queries recorded:" << std::endl; std::cout << table.size() << " queries recorded:" << std::endl;
for (auto it : table) { for (auto it : table) {
std::cout << "Time: " << it.first.ts << " PID: " << it.first.pid std::cout << "Time: " << it.first.ts << " PID: " << it.first.pid
......
...@@ -78,10 +78,10 @@ int main(int argc, char** argv) { ...@@ -78,10 +78,10 @@ int main(int argc, char** argv) {
auto table = auto table =
bpf.get_hash_table<stack_key_t, uint64_t>("counts").get_table_offline(); bpf.get_hash_table<stack_key_t, uint64_t>("counts").get_table_offline();
std::sort(table.begin(), table.end(), [](std::pair<stack_key_t, uint64_t> a, std::sort(
std::pair<stack_key_t, uint64_t> b) { table.begin(), table.end(),
return a.second < b.second; [](std::pair<stack_key_t, uint64_t> a,
}); std::pair<stack_key_t, uint64_t> b) { return a.second < b.second; });
auto stacks = bpf.get_stack_table("stack_traces"); auto stacks = bpf.get_stack_table("stack_traces");
for (auto it : table) { for (auto it : table) {
......
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
namespace ebpf { namespace ebpf {
static const char *syscall_prefix[] = { static const char* syscall_prefix[] = {
"sys_", "sys_",
"__x64_sys_", "__x64_sys_",
}; };
std::string uint_to_hex(uint64_t value) { std::string uint_to_hex(uint64_t value) {
...@@ -63,7 +63,7 @@ StatusTuple BPF::init(const std::string& bpf_program, ...@@ -63,7 +63,7 @@ StatusTuple BPF::init(const std::string& bpf_program,
const std::vector<USDT>& usdt) { const std::vector<USDT>& usdt) {
std::string all_bpf_program; std::string all_bpf_program;
bcc_symbol_option symbol_option = {}; bcc_symbol_option symbol_option = {};
void *ksym_cache; void* ksym_cache;
uint64_t addr; uint64_t addr;
int ret; int ret;
...@@ -284,8 +284,8 @@ StatusTuple BPF::attach_tracepoint(const std::string& tracepoint, ...@@ -284,8 +284,8 @@ StatusTuple BPF::attach_tracepoint(const std::string& tracepoint,
int probe_fd; int probe_fd;
TRY2(load_func(probe_func, BPF_PROG_TYPE_TRACEPOINT, probe_fd)); TRY2(load_func(probe_func, BPF_PROG_TYPE_TRACEPOINT, probe_fd));
int res_fd = bpf_attach_tracepoint(probe_fd, tp_category.c_str(), int res_fd =
tp_name.c_str()); bpf_attach_tracepoint(probe_fd, tp_category.c_str(), tp_name.c_str());
if (res_fd < 0) { if (res_fd < 0) {
TRY2(unload_func(probe_func)); TRY2(unload_func(probe_func));
...@@ -341,8 +341,8 @@ StatusTuple BPF::attach_perf_event(uint32_t ev_type, uint32_t ev_config, ...@@ -341,8 +341,8 @@ StatusTuple BPF::attach_perf_event(uint32_t ev_type, uint32_t ev_config,
} }
StatusTuple BPF::attach_perf_event_raw(void* perf_event_attr, StatusTuple BPF::attach_perf_event_raw(void* perf_event_attr,
const std::string& probe_func, const std::string& probe_func, pid_t pid,
pid_t pid, int cpu, int group_fd) { int cpu, int group_fd) {
auto attr = static_cast<struct perf_event_attr*>(perf_event_attr); auto attr = static_cast<struct perf_event_attr*>(perf_event_attr);
auto ev_pair = std::make_pair(attr->type, attr->config); auto ev_pair = std::make_pair(attr->type, attr->config);
if (perf_events_.find(ev_pair) != perf_events_.end()) if (perf_events_.find(ev_pair) != perf_events_.end())
...@@ -377,7 +377,6 @@ StatusTuple BPF::attach_perf_event_raw(void* perf_event_attr, ...@@ -377,7 +377,6 @@ StatusTuple BPF::attach_perf_event_raw(void* perf_event_attr,
p.per_cpu_fd = fds; p.per_cpu_fd = fds;
perf_events_[ev_pair] = std::move(p); perf_events_[ev_pair] = std::move(p);
return StatusTuple(0); return StatusTuple(0);
} }
StatusTuple BPF::detach_kprobe(const std::string& kernel_func, StatusTuple BPF::detach_kprobe(const std::string& kernel_func,
...@@ -567,7 +566,7 @@ StatusTuple BPF::unload_func(const std::string& func_name) { ...@@ -567,7 +566,7 @@ StatusTuple BPF::unload_func(const std::string& func_name) {
return StatusTuple(0); return StatusTuple(0);
} }
std::string BPF::get_syscall_fnname(const std::string &name) { std::string BPF::get_syscall_fnname(const std::string& name) {
std::string fn_name = syscall_prefix[syscall_prefix_idx_] + name; std::string fn_name = syscall_prefix[syscall_prefix_idx_] + name;
return std::move(fn_name); return std::move(fn_name);
} }
......
...@@ -47,7 +47,8 @@ class BPF { ...@@ -47,7 +47,8 @@ class BPF {
explicit BPF(unsigned int flag = 0, TableStorage* ts = nullptr, explicit BPF(unsigned int flag = 0, TableStorage* ts = nullptr,
bool rw_engine_enabled = true) bool rw_engine_enabled = true)
: flag_(flag), syscall_prefix_idx_(0), : flag_(flag),
syscall_prefix_idx_(0),
bpf_module_(new BPFModule(flag, ts, rw_engine_enabled)) {} bpf_module_(new BPFModule(flag, ts, rw_engine_enabled)) {}
StatusTuple init(const std::string& bpf_program, StatusTuple init(const std::string& bpf_program,
const std::vector<std::string>& cflags = {}, const std::vector<std::string>& cflags = {},
...@@ -91,7 +92,7 @@ class BPF { ...@@ -91,7 +92,7 @@ class BPF {
int group_fd = -1); int group_fd = -1);
StatusTuple detach_perf_event(uint32_t ev_type, uint32_t ev_config); StatusTuple detach_perf_event(uint32_t ev_type, uint32_t ev_config);
StatusTuple detach_perf_event_raw(void* perf_event_attr); StatusTuple detach_perf_event_raw(void* perf_event_attr);
std::string get_syscall_fnname(const std::string &name); std::string get_syscall_fnname(const std::string& name);
BPFTable get_table(const std::string& name) { BPFTable get_table(const std::string& name) {
TableStorage::iterator it; TableStorage::iterator it;
...@@ -109,7 +110,8 @@ class BPF { ...@@ -109,7 +110,8 @@ class BPF {
} }
template <class ValueType> template <class ValueType>
BPFPercpuArrayTable<ValueType> get_percpu_array_table(const std::string& name) { BPFPercpuArrayTable<ValueType> get_percpu_array_table(
const std::string& name) {
TableStorage::iterator it; TableStorage::iterator it;
if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it)) if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
return BPFPercpuArrayTable<ValueType>(it->second); return BPFPercpuArrayTable<ValueType>(it->second);
...@@ -125,7 +127,8 @@ class BPF { ...@@ -125,7 +127,8 @@ class BPF {
} }
template <class KeyType, class ValueType> template <class KeyType, class ValueType>
BPFPercpuHashTable<KeyType, ValueType> get_percpu_hash_table(const std::string& name) { BPFPercpuHashTable<KeyType, ValueType> get_percpu_hash_table(
const std::string& name) {
TableStorage::iterator it; TableStorage::iterator it;
if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it)) if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
return BPFPercpuHashTable<KeyType, ValueType>(it->second); return BPFPercpuHashTable<KeyType, ValueType>(it->second);
...@@ -159,9 +162,9 @@ class BPF { ...@@ -159,9 +162,9 @@ class BPF {
BPFPerfBuffer* get_perf_buffer(const std::string& name); BPFPerfBuffer* get_perf_buffer(const std::string& name);
// Poll an opened Perf Buffer of given name with given timeout, using callback // Poll an opened Perf Buffer of given name with given timeout, using callback
// provided when opening. Do nothing if such open Perf Buffer doesn't exist. // provided when opening. Do nothing if such open Perf Buffer doesn't exist.
// Returns: // Returns:
// -1 on error or if perf buffer with such name doesn't exist; // -1 on error or if perf buffer with such name doesn't exist;
// 0, if no data was available before timeout; // 0, if no data was available before timeout;
// number of CPUs that have new data, otherwise. // number of CPUs that have new data, otherwise.
int poll_perf_buffer(const std::string& name, int timeout_ms = -1); int poll_perf_buffer(const std::string& name, int timeout_ms = -1);
......
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
#include <fcntl.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <cerrno> #include <cerrno>
#include <cinttypes> #include <cinttypes>
...@@ -145,28 +145,25 @@ StatusTuple BPFTable::remove_value(const std::string& key_str) { ...@@ -145,28 +145,25 @@ StatusTuple BPFTable::remove_value(const std::string& key_str) {
} }
StatusTuple BPFTable::clear_table_non_atomic() { StatusTuple BPFTable::clear_table_non_atomic() {
if (desc.type == BPF_MAP_TYPE_HASH || if (desc.type == BPF_MAP_TYPE_HASH || desc.type == BPF_MAP_TYPE_PERCPU_HASH ||
desc.type == BPF_MAP_TYPE_PERCPU_HASH ||
desc.type == BPF_MAP_TYPE_LRU_HASH || desc.type == BPF_MAP_TYPE_LRU_HASH ||
desc.type == BPF_MAP_TYPE_PERCPU_HASH || desc.type == BPF_MAP_TYPE_PERCPU_HASH ||
desc.type == BPF_MAP_TYPE_HASH_OF_MAPS) { desc.type == BPF_MAP_TYPE_HASH_OF_MAPS) {
// For hash maps, use the first() interface (which uses get_next_key) to // For hash maps, use the first() interface (which uses get_next_key) to
// iterate through the map and clear elements // iterate through the map and clear elements
auto key = std::unique_ptr<void, decltype(::free)*>( auto key = std::unique_ptr<void, decltype(::free)*>(::malloc(desc.key_size),
::malloc(desc.key_size), ::free);
::free);
while (this->first(key.get())) while (this->first(key.get()))
if (!this->remove(key.get())) { if (!this->remove(key.get())) {
return StatusTuple( return StatusTuple(-1,
-1, "Failed to delete element when clearing table %s",
"Failed to delete element when clearing table %s", desc.name.c_str());
desc.name.c_str());
} }
} else if (desc.type == BPF_MAP_TYPE_ARRAY || } else if (desc.type == BPF_MAP_TYPE_ARRAY ||
desc.type == BPF_MAP_TYPE_PERCPU_ARRAY) { desc.type == BPF_MAP_TYPE_PERCPU_ARRAY) {
return StatusTuple( return StatusTuple(-1, "Array map %s do not support clearing elements",
-1, "Array map %s do not support clearing elements", desc.name.c_str()); desc.name.c_str());
} else if (desc.type == BPF_MAP_TYPE_PROG_ARRAY || } else if (desc.type == BPF_MAP_TYPE_PROG_ARRAY ||
desc.type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || desc.type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
desc.type == BPF_MAP_TYPE_STACK_TRACE || desc.type == BPF_MAP_TYPE_STACK_TRACE ||
...@@ -176,29 +173,25 @@ StatusTuple BPFTable::clear_table_non_atomic() { ...@@ -176,29 +173,25 @@ StatusTuple BPFTable::clear_table_non_atomic() {
this->remove(&i); this->remove(&i);
} }
} else { } else {
return StatusTuple( return StatusTuple(-1, "Clearing for map type of %s not supported yet",
-1, "Clearing for map type of %s not supported yet", desc.name.c_str()); desc.name.c_str());
} }
return StatusTuple(0); return StatusTuple(0);
} }
size_t BPFTable::get_possible_cpu_count() { size_t BPFTable::get_possible_cpu_count() { return get_possible_cpus().size(); }
return get_possible_cpus().size();
}
BPFStackTable::BPFStackTable(const TableDesc& desc, BPFStackTable::BPFStackTable(const TableDesc& desc, bool use_debug_file,
bool use_debug_file,
bool check_debug_file_crc) bool check_debug_file_crc)
: BPFTableBase<int, stacktrace_t>(desc) { : BPFTableBase<int, stacktrace_t>(desc) {
if (desc.type != BPF_MAP_TYPE_STACK_TRACE) if (desc.type != BPF_MAP_TYPE_STACK_TRACE)
throw std::invalid_argument("Table '" + desc.name + "' is not a stack table"); throw std::invalid_argument("Table '" + desc.name +
"' is not a stack table");
symbol_option_ = { symbol_option_ = {.use_debug_file = use_debug_file,
.use_debug_file = use_debug_file, .check_debug_file_crc = check_debug_file_crc,
.check_debug_file_crc = check_debug_file_crc, .use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC)};
.use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC)
};
} }
BPFStackTable::BPFStackTable(BPFStackTable&& that) BPFStackTable::BPFStackTable(BPFStackTable&& that)
...@@ -258,9 +251,10 @@ std::vector<std::string> BPFStackTable::get_stack_symbol(int stack_id, ...@@ -258,9 +251,10 @@ std::vector<std::string> BPFStackTable::get_stack_symbol(int stack_id,
} }
BPFPerfBuffer::BPFPerfBuffer(const TableDesc& desc) BPFPerfBuffer::BPFPerfBuffer(const TableDesc& desc)
: BPFTableBase<int, int>(desc), epfd_(-1) { : BPFTableBase<int, int>(desc), epfd_(-1) {
if (desc.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) if (desc.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY)
throw std::invalid_argument("Table '" + desc.name + "' is not a perf buffer"); throw std::invalid_argument("Table '" + desc.name +
"' is not a perf buffer");
} }
StatusTuple BPFPerfBuffer::open_on_cpu(perf_reader_raw_cb cb, StatusTuple BPFPerfBuffer::open_on_cpu(perf_reader_raw_cb cb,
...@@ -359,7 +353,8 @@ StatusTuple BPFPerfBuffer::close_all_cpu() { ...@@ -359,7 +353,8 @@ StatusTuple BPFPerfBuffer::close_all_cpu() {
int BPFPerfBuffer::poll(int timeout_ms) { int BPFPerfBuffer::poll(int timeout_ms) {
if (epfd_ < 0) if (epfd_ < 0)
return -1; return -1;
int cnt = epoll_wait(epfd_, ep_events_.get(), cpu_readers_.size(), timeout_ms); int cnt =
epoll_wait(epfd_, ep_events_.get(), cpu_readers_.size(), timeout_ms);
for (int i = 0; i < cnt; i++) for (int i = 0; i < cnt; i++)
perf_reader_event_read(static_cast<perf_reader*>(ep_events_[i].data.ptr)); perf_reader_event_read(static_cast<perf_reader*>(ep_events_[i].data.ptr));
return cnt; return cnt;
...@@ -373,9 +368,10 @@ BPFPerfBuffer::~BPFPerfBuffer() { ...@@ -373,9 +368,10 @@ BPFPerfBuffer::~BPFPerfBuffer() {
} }
BPFPerfEventArray::BPFPerfEventArray(const TableDesc& desc) BPFPerfEventArray::BPFPerfEventArray(const TableDesc& desc)
: BPFTableBase<int, int>(desc) { : BPFTableBase<int, int>(desc) {
if (desc.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) if (desc.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY)
throw std::invalid_argument("Table '" + desc.name + "' is not a perf event array"); throw std::invalid_argument("Table '" + desc.name +
"' is not a perf event array");
} }
StatusTuple BPFPerfEventArray::open_all_cpu(uint32_t type, uint64_t config) { StatusTuple BPFPerfEventArray::open_all_cpu(uint32_t type, uint64_t config) {
...@@ -426,8 +422,8 @@ StatusTuple BPFPerfEventArray::open_on_cpu(int cpu, uint32_t type, ...@@ -426,8 +422,8 @@ StatusTuple BPFPerfEventArray::open_on_cpu(int cpu, uint32_t type,
} }
if (!update(&cpu, &fd)) { if (!update(&cpu, &fd)) {
bpf_close_perf_event_fd(fd); bpf_close_perf_event_fd(fd);
return StatusTuple(-1, "Unable to open perf event on CPU %d: %s", return StatusTuple(-1, "Unable to open perf event on CPU %d: %s", cpu,
cpu, std::strerror(errno)); std::strerror(errno));
} }
cpu_fds_[cpu] = fd; cpu_fds_[cpu] = fd;
return StatusTuple(0); return StatusTuple(0);
...@@ -452,9 +448,10 @@ BPFPerfEventArray::~BPFPerfEventArray() { ...@@ -452,9 +448,10 @@ BPFPerfEventArray::~BPFPerfEventArray() {
} }
BPFProgTable::BPFProgTable(const TableDesc& desc) BPFProgTable::BPFProgTable(const TableDesc& desc)
: BPFTableBase<int, int>(desc) { : BPFTableBase<int, int>(desc) {
if (desc.type != BPF_MAP_TYPE_PROG_ARRAY) if (desc.type != BPF_MAP_TYPE_PROG_ARRAY)
throw std::invalid_argument("Table '" + desc.name + "' is not a prog table"); throw std::invalid_argument("Table '" + desc.name +
"' is not a prog table");
} }
StatusTuple BPFProgTable::update_value(const int& index, const int& prog_fd) { StatusTuple BPFProgTable::update_value(const int& index, const int& prog_fd) {
...@@ -470,9 +467,10 @@ StatusTuple BPFProgTable::remove_value(const int& index) { ...@@ -470,9 +467,10 @@ StatusTuple BPFProgTable::remove_value(const int& index) {
} }
BPFCgroupArray::BPFCgroupArray(const TableDesc& desc) BPFCgroupArray::BPFCgroupArray(const TableDesc& desc)
: BPFTableBase<int, int>(desc) { : BPFTableBase<int, int>(desc) {
if (desc.type != BPF_MAP_TYPE_CGROUP_ARRAY) if (desc.type != BPF_MAP_TYPE_CGROUP_ARRAY)
throw std::invalid_argument("Table '" + desc.name + "' is not a cgroup array"); throw std::invalid_argument("Table '" + desc.name +
"' is not a cgroup array");
} }
StatusTuple BPFCgroupArray::update_value(const int& index, StatusTuple BPFCgroupArray::update_value(const int& index,
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
#pragma once #pragma once
#include <cstring>
#include <errno.h> #include <errno.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <cstring>
#include <exception> #include <exception>
#include <map> #include <map>
#include <memory> #include <memory>
...@@ -83,9 +83,7 @@ class BPFTableBase { ...@@ -83,9 +83,7 @@ class BPFTableBase {
return bpf_update_elem(desc.fd, key, value, 0) >= 0; return bpf_update_elem(desc.fd, key, value, 0) >= 0;
} }
bool remove(void* key) { bool remove(void* key) { return bpf_delete_elem(desc.fd, key) >= 0; }
return bpf_delete_elem(desc.fd, key) >= 0;
}
const TableDesc& desc; const TableDesc& desc;
}; };
...@@ -111,19 +109,23 @@ class BPFTable : public BPFTableBase<void, void> { ...@@ -111,19 +109,23 @@ class BPFTable : public BPFTableBase<void, void> {
}; };
template <class ValueType> template <class ValueType>
void * get_value_addr(ValueType& t) { return &t; } void* get_value_addr(ValueType& t) {
return &t;
}
template <class ValueType> template <class ValueType>
void * get_value_addr(std::vector<ValueType>& t) { return t.data(); } void* get_value_addr(std::vector<ValueType>& t) {
return t.data();
}
template <class ValueType> template <class ValueType>
class BPFArrayTable : public BPFTableBase<int, ValueType> { class BPFArrayTable : public BPFTableBase<int, ValueType> {
public: public:
BPFArrayTable(const TableDesc& desc) BPFArrayTable(const TableDesc& desc) : BPFTableBase<int, ValueType>(desc) {
: BPFTableBase<int, ValueType>(desc) {
if (desc.type != BPF_MAP_TYPE_ARRAY && if (desc.type != BPF_MAP_TYPE_ARRAY &&
desc.type != BPF_MAP_TYPE_PERCPU_ARRAY) desc.type != BPF_MAP_TYPE_PERCPU_ARRAY)
throw std::invalid_argument("Table '" + desc.name + "' is not an array table"); throw std::invalid_argument("Table '" + desc.name +
"' is not an array table");
} }
virtual StatusTuple get_value(const int& index, ValueType& value) { virtual StatusTuple get_value(const int& index, ValueType& value) {
...@@ -133,7 +135,8 @@ public: ...@@ -133,7 +135,8 @@ public:
} }
virtual StatusTuple update_value(const int& index, const ValueType& value) { virtual StatusTuple update_value(const int& index, const ValueType& value) {
if (!this->update(const_cast<int*>(&index), get_value_addr(const_cast<ValueType&>(value)))) if (!this->update(const_cast<int*>(&index),
get_value_addr(const_cast<ValueType&>(value))))
return StatusTuple(-1, "Error updating value: %s", std::strerror(errno)); return StatusTuple(-1, "Error updating value: %s", std::strerror(errno));
return StatusTuple(0); return StatusTuple(0);
} }
...@@ -147,7 +150,7 @@ public: ...@@ -147,7 +150,7 @@ public:
std::vector<ValueType> get_table_offline() { std::vector<ValueType> get_table_offline() {
std::vector<ValueType> res(this->capacity()); std::vector<ValueType> res(this->capacity());
for (int i = 0; i < (int) this->capacity(); i++) { for (int i = 0; i < (int)this->capacity(); i++) {
get_value(i, res[i]); get_value(i, res[i]);
} }
...@@ -162,8 +165,10 @@ class BPFPercpuArrayTable : public BPFArrayTable<std::vector<ValueType>> { ...@@ -162,8 +165,10 @@ class BPFPercpuArrayTable : public BPFArrayTable<std::vector<ValueType>> {
: BPFArrayTable<std::vector<ValueType>>(desc), : BPFArrayTable<std::vector<ValueType>>(desc),
ncpus(BPFTable::get_possible_cpu_count()) { ncpus(BPFTable::get_possible_cpu_count()) {
if (desc.type != BPF_MAP_TYPE_PERCPU_ARRAY) if (desc.type != BPF_MAP_TYPE_PERCPU_ARRAY)
throw std::invalid_argument("Table '" + desc.name + "' is not a percpu array table"); throw std::invalid_argument("Table '" + desc.name +
// leaf structures have to be aligned to 8 bytes as hardcoded in the linux kernel. "' is not a percpu array table");
// leaf structures have to be aligned to 8 bytes as hardcoded in the linux
// kernel.
if (sizeof(ValueType) % 8) if (sizeof(ValueType) % 8)
throw std::invalid_argument("leaf must be aligned to 8 bytes"); throw std::invalid_argument("leaf must be aligned to 8 bytes");
} }
...@@ -173,11 +178,13 @@ class BPFPercpuArrayTable : public BPFArrayTable<std::vector<ValueType>> { ...@@ -173,11 +178,13 @@ class BPFPercpuArrayTable : public BPFArrayTable<std::vector<ValueType>> {
return BPFArrayTable<std::vector<ValueType>>::get_value(index, value); return BPFArrayTable<std::vector<ValueType>>::get_value(index, value);
} }
StatusTuple update_value(const int& index, const std::vector<ValueType>& value) { StatusTuple update_value(const int& index,
const std::vector<ValueType>& value) {
if (value.size() != ncpus) if (value.size() != ncpus)
return StatusTuple(-1, "bad value size"); return StatusTuple(-1, "bad value size");
return BPFArrayTable<std::vector<ValueType>>::update_value(index, value); return BPFArrayTable<std::vector<ValueType>>::update_value(index, value);
} }
private: private:
unsigned int ncpus; unsigned int ncpus;
}; };
...@@ -191,7 +198,8 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> { ...@@ -191,7 +198,8 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> {
desc.type != BPF_MAP_TYPE_PERCPU_HASH && desc.type != BPF_MAP_TYPE_PERCPU_HASH &&
desc.type != BPF_MAP_TYPE_LRU_HASH && desc.type != BPF_MAP_TYPE_LRU_HASH &&
desc.type != BPF_MAP_TYPE_LRU_PERCPU_HASH) desc.type != BPF_MAP_TYPE_LRU_PERCPU_HASH)
throw std::invalid_argument("Table '" + desc.name + "' is not a hash table"); throw std::invalid_argument("Table '" + desc.name +
"' is not a hash table");
} }
virtual StatusTuple get_value(const KeyType& key, ValueType& value) { virtual StatusTuple get_value(const KeyType& key, ValueType& value) {
...@@ -201,7 +209,8 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> { ...@@ -201,7 +209,8 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> {
} }
virtual StatusTuple update_value(const KeyType& key, const ValueType& value) { virtual StatusTuple update_value(const KeyType& key, const ValueType& value) {
if (!this->update(const_cast<KeyType*>(&key), get_value_addr(const_cast<ValueType&>(value)))) if (!this->update(const_cast<KeyType*>(&key),
get_value_addr(const_cast<ValueType&>(value))))
return StatusTuple(-1, "Error updating value: %s", std::strerror(errno)); return StatusTuple(-1, "Error updating value: %s", std::strerror(errno));
return StatusTuple(0); return StatusTuple(0);
} }
...@@ -247,15 +256,18 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> { ...@@ -247,15 +256,18 @@ class BPFHashTable : public BPFTableBase<KeyType, ValueType> {
}; };
template <class KeyType, class ValueType> template <class KeyType, class ValueType>
class BPFPercpuHashTable : public BPFHashTable<KeyType, std::vector<ValueType>> { class BPFPercpuHashTable
: public BPFHashTable<KeyType, std::vector<ValueType>> {
public: public:
explicit BPFPercpuHashTable(const TableDesc& desc) explicit BPFPercpuHashTable(const TableDesc& desc)
: BPFHashTable<KeyType, std::vector<ValueType>>(desc), : BPFHashTable<KeyType, std::vector<ValueType>>(desc),
ncpus(BPFTable::get_possible_cpu_count()) { ncpus(BPFTable::get_possible_cpu_count()) {
if (desc.type != BPF_MAP_TYPE_PERCPU_HASH && if (desc.type != BPF_MAP_TYPE_PERCPU_HASH &&
desc.type != BPF_MAP_TYPE_LRU_PERCPU_HASH) desc.type != BPF_MAP_TYPE_LRU_PERCPU_HASH)
throw std::invalid_argument("Table '" + desc.name + "' is not a percpu hash table"); throw std::invalid_argument("Table '" + desc.name +
// leaf structures have to be aligned to 8 bytes as hardcoded in the linux kernel. "' is not a percpu hash table");
// leaf structures have to be aligned to 8 bytes as hardcoded in the linux
// kernel.
if (sizeof(ValueType) % 8) if (sizeof(ValueType) % 8)
throw std::invalid_argument("leaf must be aligned to 8 bytes"); throw std::invalid_argument("leaf must be aligned to 8 bytes");
} }
...@@ -265,11 +277,14 @@ class BPFPercpuHashTable : public BPFHashTable<KeyType, std::vector<ValueType>> ...@@ -265,11 +277,14 @@ class BPFPercpuHashTable : public BPFHashTable<KeyType, std::vector<ValueType>>
return BPFHashTable<KeyType, std::vector<ValueType>>::get_value(key, value); return BPFHashTable<KeyType, std::vector<ValueType>>::get_value(key, value);
} }
StatusTuple update_value(const KeyType& key, const std::vector<ValueType>& value) { StatusTuple update_value(const KeyType& key,
const std::vector<ValueType>& value) {
if (value.size() != ncpus) if (value.size() != ncpus)
return StatusTuple(-1, "bad value size"); return StatusTuple(-1, "bad value size");
return BPFHashTable<KeyType, std::vector<ValueType>>::update_value(key, value); return BPFHashTable<KeyType, std::vector<ValueType>>::update_value(key,
value);
} }
private: private:
unsigned int ncpus; unsigned int ncpus;
}; };
...@@ -282,8 +297,7 @@ struct stacktrace_t { ...@@ -282,8 +297,7 @@ struct stacktrace_t {
class BPFStackTable : public BPFTableBase<int, stacktrace_t> { class BPFStackTable : public BPFTableBase<int, stacktrace_t> {
public: public:
BPFStackTable(const TableDesc& desc, BPFStackTable(const TableDesc& desc, bool use_debug_file,
bool use_debug_file,
bool check_debug_file_crc); bool check_debug_file_crc);
BPFStackTable(BPFStackTable&& that); BPFStackTable(BPFStackTable&& that);
~BPFStackTable(); ~BPFStackTable();
...@@ -334,7 +348,7 @@ class BPFPerfEventArray : public BPFTableBase<int, int> { ...@@ -334,7 +348,7 @@ class BPFPerfEventArray : public BPFTableBase<int, int> {
}; };
class BPFProgTable : public BPFTableBase<int, int> { class BPFProgTable : public BPFTableBase<int, int> {
public: public:
BPFProgTable(const TableDesc& desc); BPFProgTable(const TableDesc& desc);
StatusTuple update_value(const int& index, const int& prog_fd); StatusTuple update_value(const int& index, const int& prog_fd);
...@@ -342,7 +356,7 @@ public: ...@@ -342,7 +356,7 @@ public:
}; };
class BPFCgroupArray : public BPFTableBase<int, int> { class BPFCgroupArray : public BPFTableBase<int, int> {
public: public:
BPFCgroupArray(const TableDesc& desc); BPFCgroupArray(const TableDesc& desc);
StatusTuple update_value(const int& index, const int& cgroup2_fd); StatusTuple update_value(const int& index, const int& cgroup2_fd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment