Make sure both user space and bpf programs can correctly manipulate the KV store. In the first loop, for each key, we first try to get the value, this should fail as it is not yet initialized. Then, we put the value as the key. In the second loop, for each key, a bpf program is triggered to get the value, and then put a new value. In the final loop, we get the value again in the user space and make sure they are the new value. Signed-off-by: Amery Hung <ameryhung@xxxxxxxxx> --- .../bpf/prog_tests/test_uptr_kv_store.c | 77 +++++++++++++++++++ .../selftests/bpf/progs/test_uptr_kv_store.c | 37 +++++++++ .../selftests/bpf/test_uptr_kv_store_common.h | 9 +++ 3 files changed, 123 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/test_uptr_kv_store.c create mode 100644 tools/testing/selftests/bpf/progs/test_uptr_kv_store.c create mode 100644 tools/testing/selftests/bpf/test_uptr_kv_store_common.h diff --git a/tools/testing/selftests/bpf/prog_tests/test_uptr_kv_store.c b/tools/testing/selftests/bpf/prog_tests/test_uptr_kv_store.c new file mode 100644 index 000000000000..2075b8e47972 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/test_uptr_kv_store.c @@ -0,0 +1,77 @@ +#include <test_progs.h> + +#include "uptr_kv_store.h" +#include "test_uptr_kv_store_common.h" +#include "test_uptr_kv_store.skel.h" + +static void test_uptr_kv_store_basic(void) +{ + int err, i, pid, int_val, *int_val_p, max_int_entries; + struct test_uptr_kv_store *skel; + struct kv_store *kvs = NULL; + + skel = test_uptr_kv_store__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) + return; + + skel->bss->target_pid = -1; + err = test_uptr_kv_store__attach(skel); + if (!ASSERT_OK(err, "skel_attach")) + return; + + kvs = kv_store_init(getpid(), skel->maps.data_map, "/sys/fs/bpf/kv_store_data_map"); + if (!ASSERT_OK_PTR(kvs, "kv_store_init")) + return; + + max_int_entries = KVS_MAX_VAL_ENTRIES; + + err = kv_store_update_value_size(kvs, 0, KVS_MAX_VAL_SIZE); + ASSERT_ERR(err, "kv_store_update_value_size"); + + err = kv_store_put(kvs, 0, &int_val, KVS_MAX_VAL_SIZE + 1); + ASSERT_ERR(err, "kv_store_put"); + + for (i = 0; i < max_int_entries; i++) { + int_val_p = kv_store_get(kvs, i); + if (!ASSERT_ERR_PTR(int_val_p, "kv_store_get int_val")) + goto out; + + err = kv_store_put(kvs, i, &i, sizeof(i)); + if (!ASSERT_OK(err, "kv_store_put int_val")) + goto out; + } + + pid = sys_gettid(); + skel->bss->target_pid = pid; + for (i = 0; i < max_int_entries; i++) { + skel->bss->test_key = i; + skel->bss->test_op = KVS_INT_GET; + sys_gettid(); + ASSERT_EQ(skel->bss->test_int_val, i, "bpf: check int_val[i] = i"); + + skel->bss->test_int_val += 1; + skel->bss->test_op = KVS_INT_PUT; + sys_gettid(); + } + skel->bss->target_pid = -1; + + for (i = 0; i < max_int_entries; i++) { + int_val_p = kv_store_get(kvs, i); + if (!ASSERT_OK_PTR(int_val_p, "kv_store_get int_val")) + goto out; + + ASSERT_EQ(*int_val_p, i + 1, "user space: check int_val[i] == i + 1"); + } + + err = kv_store_put(kvs, max_int_entries, &int_val, sizeof(int)); + ASSERT_EQ(err, -ENOENT, "kv_store_put int_val"); + +out: + kv_store_close(kvs); +} + +void test_uptr_kv_store(void) +{ + if (test__start_subtest("uptr_kv_store_basic")) + test_uptr_kv_store_basic(); +} diff --git a/tools/testing/selftests/bpf/progs/test_uptr_kv_store.c b/tools/testing/selftests/bpf/progs/test_uptr_kv_store.c new file mode 100644 index 000000000000..b358cb7fb616 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_uptr_kv_store.c @@ -0,0 +1,37 @@ +#include <vmlinux.h> +#include <bpf/bpf_helpers.h> + +#include "uptr_kv_store.h" +#include "test_uptr_kv_store_common.h" + +pid_t target_pid = 0; +int test_op; +int test_key; +int test_int_val; + +SEC("tp_btf/sys_enter") +int on_enter(__u64 *ctx) +{ + struct kv_store_data_map_value *data; + struct task_struct *task; + + task = bpf_get_current_task_btf(); + if (task->pid != target_pid) + return 0; + + data = bpf_task_storage_get(&data_map, task, 0, 0); + + switch (test_op) { + case KVS_INT_PUT: + kv_store_put(data, test_key, &test_int_val, 4); + break; + case KVS_INT_GET: + kv_store_get(data, test_key, &test_int_val, 4); + break; + } + + return 0; +} + +char _license[] SEC("license") = "GPL"; + diff --git a/tools/testing/selftests/bpf/test_uptr_kv_store_common.h b/tools/testing/selftests/bpf/test_uptr_kv_store_common.h new file mode 100644 index 000000000000..ff7d010ed08f --- /dev/null +++ b/tools/testing/selftests/bpf/test_uptr_kv_store_common.h @@ -0,0 +1,9 @@ +#ifndef _TEST_UPTR_KV_STORE_COMMON_H +#define _TEST_UPTR_KV_STORE_COMMON_H + +enum test_kvs_op { + KVS_INT_GET, + KVS_INT_PUT, +}; + +#endif -- 2.47.1