Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
kenlig committed Oct 19, 2024
1 parent 2bc9767 commit f66e70d
Show file tree
Hide file tree
Showing 6 changed files with 380 additions and 161 deletions.
72 changes: 58 additions & 14 deletions runtime/src/bpf_map/userspace/per_cpu_hash_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,40 @@
* All rights reserved.
*/
#include "bpf_map/map_common_def.hpp"
#include "linux/bpf.h"
#include "spdlog/fmt/bin_to_hex.h"
#include "spdlog/spdlog.h"
#include <algorithm>
#include <bpf_map/userspace/per_cpu_hash_map.hpp>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include "platform_utils.hpp"

static inline bool check_update_flags(uint64_t flags)
{
if (flags != BPF_ANY && flags != BPF_NOEXIST && flags != BPF_EXIST) {
errno = EINVAL;
return false;
}
return true;
}

namespace bpftime
{
per_cpu_hash_map_impl::per_cpu_hash_map_impl(
boost::interprocess::managed_shared_memory &memory, uint32_t key_size,
uint32_t value_size)
: per_cpu_hash_map_impl(memory, key_size, value_size,
uint32_t value_size, uint32_t max_entries)
: per_cpu_hash_map_impl(memory, key_size, value_size, max_entries,
sysconf(_SC_NPROCESSORS_ONLN))
{
}

per_cpu_hash_map_impl::per_cpu_hash_map_impl(
boost::interprocess::managed_shared_memory &memory, uint32_t key_size,
uint32_t value_size, int ncpu)
uint32_t value_size, uint32_t max_entries, int ncpu)
: impl(memory.get_segment_manager()), key_size(key_size),
value_size(value_size), ncpu(ncpu),
value_size(value_size), ncpu(ncpu), _max_entries(max_entries),
value_template(value_size * ncpu, memory.get_segment_manager()),
key_templates(memory.get_segment_manager()),
single_value_templates(memory.get_segment_manager())
Expand Down Expand Up @@ -64,6 +76,8 @@ void *per_cpu_hash_map_impl::elem_lookup(const void *key)
long per_cpu_hash_map_impl::elem_update(const void *key, const void *value,
uint64_t flags)
{
if (!check_update_flags(flags))
return -1;
int cpu = my_sched_getcpu();
SPDLOG_DEBUG("Per cpu update, key {}, value {}", (const char *)key,
*(long *)value);
Expand Down Expand Up @@ -115,7 +129,7 @@ int per_cpu_hash_map_impl::map_get_next_key(const void *key, void *next_key)
}
// No need to be allocated at shm. Allocate as a local variable to make
// it thread safe, since we use sharable lock
bytes_vec key_vec = this->key_templates[0];
bytes_vec &key_vec = this->key_templates[0];
key_vec.assign((uint8_t *)key, (uint8_t *)key + key_size);

auto itr = impl.find(key_vec);
Expand All @@ -139,7 +153,7 @@ void *per_cpu_hash_map_impl::elem_lookup_userspace(const void *key)
errno = ENOENT;
return nullptr;
}
bytes_vec key_vec = this->key_templates[0];
bytes_vec &key_vec = this->key_templates[0];
key_vec.assign((uint8_t *)key, (uint8_t *)key + key_size);
if (auto itr = impl.find(key_vec); itr != impl.end()) {
SPDLOG_TRACE("Exit elem lookup of hash map: {}",
Expand All @@ -157,24 +171,54 @@ long per_cpu_hash_map_impl::elem_update_userspace(const void *key,
const void *value,
uint64_t flags)
{
bytes_vec key_vec = this->key_templates[0];
if (!check_update_flags(flags))
return -1;
bytes_vec &key_vec = this->key_templates[0];
bytes_vec value_vec = this->value_template;
key_vec.assign((uint8_t *)key, (uint8_t *)key + key_size);
value_vec.assign((uint8_t *)value,
(uint8_t *)value + value_size * ncpu);

if (auto itr = impl.find(key_vec); itr != impl.end()) {
itr->second = value_vec;
} else {
impl.insert(bi_map_value_ty(key_vec, value_vec));
bool elem_exists = impl.find(key_vec) != impl.end();
if (flags == BPF_NOEXIST && elem_exists) {
errno = EEXIST;
return -1;
}
if (flags == BPF_EXIST && !elem_exists) {
errno = ENOENT;
return -1;
}
if (elem_exists == false && impl.size() == _max_entries) {
errno = E2BIG;
return -1;
}
impl.insert_or_assign(key_vec, value_vec);
return 0;
}
long per_cpu_hash_map_impl::elem_delete_userspace(const void *key)
{
bytes_vec key_vec = this->key_templates[0];
bytes_vec &key_vec = this->key_templates[0];
key_vec.assign((uint8_t *)key, (uint8_t *)key + key_size);
impl.erase(key_vec);
auto itr = impl.find(key_vec);
if (itr == impl.end()) {
errno = ENOENT;
return -1;
}
impl.erase(itr);
return 0;
}

long per_cpu_hash_map_impl::lookup_and_delete_userspace(const void *key,
void *value)
{
bytes_vec &key_vec = this->key_templates[0];
key_vec.assign((uint8_t *)key, (uint8_t *)key + key_size);
auto itr = this->impl.find(key_vec);
if (itr == impl.end()) {
errno = ENOENT;
return -1;
}
memcpy(value, itr->second.data(), ncpu * value_size);
impl.erase(itr);
return 0;
}
} // namespace bpftime
32 changes: 25 additions & 7 deletions runtime/src/bpf_map/userspace/per_cpu_hash_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,36 @@ class per_cpu_hash_map_impl {
std::equal_to<bytes_vec>, bi_map_allocator>;

using shm_hash_map_vec_allocator = boost::interprocess::allocator<
shm_hash_map, boost::interprocess::managed_shared_memory::segment_manager>;
using shm_hash_map_vec = boost::interprocess::vector<shm_hash_map, shm_hash_map_vec_allocator>;

shm_hash_map,
boost::interprocess::managed_shared_memory::segment_manager>;
using shm_hash_map_vec =
boost::interprocess::vector<shm_hash_map,
shm_hash_map_vec_allocator>;

using bytes_vec_vec_allocator = boost::interprocess::allocator<
bytes_vec, boost::interprocess::managed_shared_memory::segment_manager>;
using bytes_vec_vec = boost::interprocess::vector<bytes_vec, bytes_vec_vec_allocator>;
bytes_vec,
boost::interprocess::managed_shared_memory::segment_manager>;
using bytes_vec_vec =
boost::interprocess::vector<bytes_vec, bytes_vec_vec_allocator>;

shm_hash_map impl;
uint32_t key_size;
uint32_t value_size;
int ncpu;
uint32_t _max_entries;

bytes_vec value_template;
bytes_vec_vec key_templates, single_value_templates;

public:
const static bool should_lock = false;

per_cpu_hash_map_impl(boost::interprocess::managed_shared_memory &memory,
uint32_t key_size, uint32_t value_size);
uint32_t key_size, uint32_t value_size,
uint32_t max_entries);
per_cpu_hash_map_impl(boost::interprocess::managed_shared_memory &memory,
uint32_t key_size, uint32_t value_size, int ncpu);
uint32_t key_size, uint32_t value_size,
uint32_t max_entries, int ncpu);
void *elem_lookup(const void *key);

long elem_update(const void *key, const void *value, uint64_t flags);
Expand All @@ -62,6 +71,15 @@ class per_cpu_hash_map_impl {
uint64_t flags);

long elem_delete_userspace(const void *key);
long lookup_and_delete_userspace(const void *key, void *value);
uint32_t get_value_size() const
{
return value_size;
}
int getncpu() const
{
return ncpu;
}
};
} // namespace bpftime

Expand Down
32 changes: 17 additions & 15 deletions runtime/src/handler/map_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const void *bpf_map_handler::map_lookup_elem(const void *key,
return from_syscall ? do_lookup_userspace(impl) :
do_lookup(impl);
}
#ifdef BPFTIME_BUILD_WITH_LIBBPF
#ifdef BPFTIME_BUILD_WITH_LIBBPF
case bpf_map_type::BPF_MAP_TYPE_KERNEL_USER_ARRAY: {
auto impl = static_cast<array_map_kernel_user_impl *>(
map_impl_ptr.get());
Expand All @@ -145,7 +145,7 @@ const void *bpf_map_handler::map_lookup_elem(const void *key,
static_cast<prog_array_map_impl *>(map_impl_ptr.get());
return do_lookup(impl);
}
#endif
#endif
case bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS: {
auto impl = static_cast<array_map_of_maps_impl *>(
map_impl_ptr.get());
Expand Down Expand Up @@ -213,7 +213,7 @@ long bpf_map_handler::map_update_elem(const void *key, const void *value,
return from_syscall ? do_update_userspace(impl) :
do_update(impl);
}
#ifdef BPFTIME_BUILD_WITH_LIBBPF
#ifdef BPFTIME_BUILD_WITH_LIBBPF
case bpf_map_type::BPF_MAP_TYPE_KERNEL_USER_ARRAY: {
auto impl = static_cast<array_map_kernel_user_impl *>(
map_impl_ptr.get());
Expand All @@ -239,7 +239,7 @@ long bpf_map_handler::map_update_elem(const void *key, const void *value,
static_cast<prog_array_map_impl *>(map_impl_ptr.get());
return do_update(impl);
}
#endif
#endif
case bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS: {
if (!from_syscall) {
// Map in maps only support update from syscall
Expand Down Expand Up @@ -300,7 +300,7 @@ int bpf_map_handler::bpf_map_get_next_key(const void *key, void *next_key,
map_impl_ptr.get());
return do_get_next_key(impl);
}
#if __linux__ && defined(BPFTIME_BUILD_WITH_LIBBPF)
#if __linux__ && defined(BPFTIME_BUILD_WITH_LIBBPF)
case bpf_map_type::BPF_MAP_TYPE_KERNEL_USER_ARRAY: {
auto impl = static_cast<array_map_kernel_user_impl *>(
map_impl_ptr.get());
Expand All @@ -326,7 +326,7 @@ int bpf_map_handler::bpf_map_get_next_key(const void *key, void *next_key,
static_cast<prog_array_map_impl *>(map_impl_ptr.get());
return do_get_next_key(impl);
}
#endif
#endif
case bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS: {
auto impl = static_cast<array_map_of_maps_impl *>(
map_impl_ptr.get());
Expand Down Expand Up @@ -394,7 +394,7 @@ long bpf_map_handler::map_delete_elem(const void *key, bool from_syscall) const
return from_syscall ? do_delete_userspace(impl) :
do_delete(impl);
}
#ifdef BPFTIME_BUILD_WITH_LIBBPF
#ifdef BPFTIME_BUILD_WITH_LIBBPF
case bpf_map_type::BPF_MAP_TYPE_KERNEL_USER_ARRAY: {
auto impl = static_cast<array_map_kernel_user_impl *>(
map_impl_ptr.get());
Expand All @@ -420,7 +420,7 @@ long bpf_map_handler::map_delete_elem(const void *key, bool from_syscall) const
static_cast<prog_array_map_impl *>(map_impl_ptr.get());
return do_delete(impl);
}
#endif
#endif
case bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS: {
if (!from_syscall) {
// Map in maps only support update from syscall
Expand All @@ -447,8 +447,9 @@ int bpf_map_handler::map_init(managed_shared_memory &memory)
auto container_name = get_container_name();
switch (type) {
case bpf_map_type::BPF_MAP_TYPE_HASH: {
map_impl_ptr = memory.construct<hash_map_impl>(
container_name.c_str())(memory, max_entries, key_size, value_size);
map_impl_ptr =
memory.construct<hash_map_impl>(container_name.c_str())(
memory, max_entries, key_size, value_size);
return 0;
}
case bpf_map_type::BPF_MAP_TYPE_ARRAY: {
Expand Down Expand Up @@ -488,10 +489,11 @@ int bpf_map_handler::map_init(managed_shared_memory &memory)
}
case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: {
map_impl_ptr = memory.construct<per_cpu_hash_map_impl>(
container_name.c_str())(memory, key_size, value_size);
container_name.c_str())(memory, key_size, value_size,
max_entries);
return 0;
}
#ifdef BPFTIME_BUILD_WITH_LIBBPF
#ifdef BPFTIME_BUILD_WITH_LIBBPF
case bpf_map_type::BPF_MAP_TYPE_KERNEL_USER_ARRAY: {
map_impl_ptr = memory.construct<array_map_kernel_user_impl>(
container_name.c_str())(memory, attr.kernel_bpf_map_id);
Expand Down Expand Up @@ -523,7 +525,7 @@ int bpf_map_handler::map_init(managed_shared_memory &memory)
max_entries);
return 0;
}
#endif
#endif
case bpf_map_type::BPF_MAP_TYPE_ARRAY_OF_MAPS: {
map_impl_ptr = memory.construct<array_map_of_maps_impl>(
container_name.c_str())(memory, max_entries);
Expand Down Expand Up @@ -570,7 +572,7 @@ void bpf_map_handler::map_free(managed_shared_memory &memory)
case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH:
memory.destroy<per_cpu_hash_map_impl>(container_name.c_str());
break;
#ifdef BPFTIME_BUILD_WITH_LIBBPF
#ifdef BPFTIME_BUILD_WITH_LIBBPF
case bpf_map_type::BPF_MAP_TYPE_KERNEL_USER_ARRAY:
memory.destroy<array_map_kernel_user_impl>(
container_name.c_str());
Expand All @@ -590,7 +592,7 @@ void bpf_map_handler::map_free(managed_shared_memory &memory)
case bpf_map_type::BPF_MAP_TYPE_PROG_ARRAY:
memory.destroy<prog_array_map_impl>(container_name.c_str());
break;
#endif
#endif
default:
auto func_ptr = global_map_ops_table[(int)type].map_free;
if (func_ptr) {
Expand Down
Loading

0 comments on commit f66e70d

Please sign in to comment.