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 5c4f296 commit dc1f725
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 16 deletions.
9 changes: 9 additions & 0 deletions runtime/src/bpf_map/map_common_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
#ifndef _MAP_COMMON_DEF_HPP
#define _MAP_COMMON_DEF_HPP
#include "linux/bpf.h"
#include "spdlog/spdlog.h"
#include <boost/container_hash/hash.hpp>
#include <cinttypes>
Expand Down Expand Up @@ -68,6 +69,14 @@ struct bytes_vec_hasher {
return seed;
}
};
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

#endif
28 changes: 20 additions & 8 deletions runtime/src/bpf_map/userspace/array_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* Copyright (c) 2022, eunomia-bpf org
* All rights reserved.
*/
#include "bpf_map/map_common_def.hpp"
#include "linux/bpf.h"
#include <bpf_map/userspace/array_map.hpp>
#include <cerrno>

Expand Down Expand Up @@ -34,9 +36,16 @@ void *array_map_impl::elem_lookup(const void *key)
long array_map_impl::elem_update(const void *key, const void *value,
uint64_t flags)
{
if (!check_update_flags(flags))
return -1;
auto key_val = *(uint32_t *)key;
if (key_val < _max_entries && flags == BPF_NOEXIST) {
errno = EEXIST;
return -1;
}

if (key_val >= _max_entries) {
errno = ENOENT;
errno = E2BIG;
return -1;
}
std::copy((uint8_t *)value, (uint8_t *)value + _value_size,
Expand All @@ -47,13 +56,16 @@ long array_map_impl::elem_update(const void *key, const void *value,
long array_map_impl::elem_delete(const void *key)
{
auto key_val = *(uint32_t *)key;
if (key_val >= _max_entries) {
errno = ENOENT;
return -1;
}
std::fill(&data[key_val * _value_size],
&data[key_val * _value_size] + _value_size, 0);
return 0;
// kernel tests says element in an array map can't be deleted...
errno = EINVAL;
return -1;
// if (key_val >= _max_entries) {
// errno = ENOENT;
// return -1;
// }
// std::fill(&data[key_val * _value_size],
// &data[key_val * _value_size] + _value_size, 0);
// return 0;
}

int array_map_impl::map_get_next_key(const void *key, void *next_key)
Expand Down
8 changes: 0 additions & 8 deletions runtime/src/bpf_map/userspace/per_cpu_hash_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@
#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
{
Expand Down
57 changes: 57 additions & 0 deletions runtime/unit-test/maps/kernel_unit_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "bpf_map/userspace/array_map.hpp"
#include "bpf_map/userspace/per_cpu_hash_map.hpp"
#include "catch2/catch_test_macros.hpp"
#include "linux/bpf.h"
Expand Down Expand Up @@ -318,3 +319,59 @@ TEST_CASE("test_hashmap_walk (kernel)")

REQUIRE(i == max_entries);
}

TEST_CASE("test_arraymap (kernel)")
{
shm_remove remover(SHM_NAME);
managed_shared_memory mem(boost::interprocess::create_only, SHM_NAME,
20 << 20);
int key, next_key;
long long value;
auto value_size = sizeof(value);
array_map_impl map(mem, sizeof(value), 2);
const auto lookup_helper = [&](const void *key, void *value) -> long {
auto returned_value = map.elem_lookup(key);
if (!returned_value)
return -1;
memcpy(value, returned_value, sizeof(value_size));
return 0;
};

key = 1;
value = 1234;
/* Insert key=1 element. */
REQUIRE(map.elem_update(&key, &value, BPF_ANY) == 0);

value = 0;
REQUIRE((map.elem_update(&key, &value, BPF_NOEXIST) < 0 &&
errno == EEXIST));

/* Check that key=1 can be found. */
REQUIRE((lookup_helper(&key, &value) == 0 && value == 1234));

key = 0;
/* Check that key=0 is also found and zero initialized. */
REQUIRE((lookup_helper(&key, &value) == 0 && value == 0));

/* key=0 and key=1 were inserted, check that key=2 cannot be inserted
* due to max_entries limit.
*/
key = 2;
REQUIRE((map.elem_update(&key, &value, BPF_EXIST) < 0 &&
errno == E2BIG));

/* Check that key = 2 doesn't exist. */
REQUIRE((lookup_helper(&key, &value) < 0 && errno == ENOENT));

/* Iterate over two elements. */
REQUIRE((map.map_get_next_key(NULL, &next_key) == 0 && next_key == 0));
REQUIRE((map.map_get_next_key(&key, &next_key) == 0 && next_key == 0));
REQUIRE((map.map_get_next_key(&next_key, &next_key) == 0 &&
next_key == 1));
REQUIRE((map.map_get_next_key(&next_key, &next_key) < 0 &&
errno == ENOENT));

/* Delete shouldn't succeed. */
key = 1;
REQUIRE((map.elem_delete(&key) < 0 && errno == EINVAL));
}

0 comments on commit dc1f725

Please sign in to comment.