selftests/bpf: Test struct_ops map definition with type suffix

Extend struct_ops_module test case to check if it is possible to use
'___' suffixes for struct_ops type specification.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: David Vernet <void@manifault.com>
Link: https://lore.kernel.org/bpf/20240306104529.6453-5-eddyz87@gmail.com
This commit is contained in:
Eduard Zingerman 2024-03-06 12:45:18 +02:00 committed by Andrii Nakryiko
parent 8db052615a
commit 5bab7a277c
3 changed files with 46 additions and 10 deletions

View File

@ -564,6 +564,8 @@ static int bpf_dummy_reg(void *kdata)
{
struct bpf_testmod_ops *ops = kdata;
if (ops->test_1)
ops->test_1();
/* Some test cases (ex. struct_ops_maybe_null) may not have test_2
* initialized, so we need to check for NULL.
*/

View File

@ -30,11 +30,29 @@ cleanup:
close(fd);
}
static int attach_ops_and_check(struct struct_ops_module *skel,
struct bpf_map *map,
int expected_test_2_result)
{
struct bpf_link *link;
link = bpf_map__attach_struct_ops(map);
ASSERT_OK_PTR(link, "attach_test_mod_1");
if (!link)
return -1;
/* test_{1,2}() would be called from bpf_dummy_reg() in bpf_testmod.c */
ASSERT_EQ(skel->bss->test_1_result, 0xdeadbeef, "test_1_result");
ASSERT_EQ(skel->bss->test_2_result, expected_test_2_result, "test_2_result");
bpf_link__destroy(link);
return 0;
}
static void test_struct_ops_load(void)
{
struct struct_ops_module *skel;
struct bpf_map_info info = {};
struct bpf_link *link;
int err;
u32 len;
@ -59,20 +77,17 @@ static void test_struct_ops_load(void)
if (!ASSERT_OK(err, "bpf_map_get_info_by_fd"))
goto cleanup;
link = bpf_map__attach_struct_ops(skel->maps.testmod_1);
ASSERT_OK_PTR(link, "attach_test_mod_1");
check_map_info(&info);
/* test_3() will be called from bpf_dummy_reg() in bpf_testmod.c
*
* In bpf_testmod.c it will pass 4 and 13 (the value of data) to
* .test_2. So, the value of test_2_result should be 20 (4 + 13 +
* 3).
*/
ASSERT_EQ(skel->bss->test_2_result, 20, "check_shadow_variables");
bpf_link__destroy(link);
check_map_info(&info);
if (!attach_ops_and_check(skel, skel->maps.testmod_1, 20))
goto cleanup;
if (!attach_ops_and_check(skel, skel->maps.testmod_2, 12))
goto cleanup;
cleanup:
struct_ops_module__destroy(skel);

View File

@ -7,12 +7,14 @@
char _license[] SEC("license") = "GPL";
int test_1_result = 0;
int test_2_result = 0;
SEC("struct_ops/test_1")
int BPF_PROG(test_1)
{
return 0xdeadbeef;
test_1_result = 0xdeadbeef;
return 0;
}
SEC("struct_ops/test_2")
@ -35,3 +37,20 @@ struct bpf_testmod_ops testmod_1 = {
.data = 0x1,
};
SEC("struct_ops/test_2")
void BPF_PROG(test_2_v2, int a, int b)
{
test_2_result = a * b;
}
struct bpf_testmod_ops___v2 {
int (*test_1)(void);
void (*test_2)(int a, int b);
int (*test_maybe_null)(int dummy, struct task_struct *task);
};
SEC(".struct_ops.link")
struct bpf_testmod_ops___v2 testmod_2 = {
.test_1 = (void *)test_1,
.test_2 = (void *)test_2_v2,
};