Commit 43d50ffb authored by Kui-Feng Lee's avatar Kui-Feng Lee Committed by Alexei Starovoitov
Browse files

selftests/bpf: Test global bpf_list_head arrays.



Make sure global arrays of bpf_list_heads and fields of bpf_list_heads in
nested struct types work correctly.

Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Signed-off-by: default avatarKui-Feng Lee <thinker.li@gmail.com>
Link: https://lore.kernel.org/r/20240523174202.461236-10-thinker.li@gmail.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent d55c765a
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -183,6 +183,18 @@ static void test_linked_list_success(int mode, bool leave_in_map)
	if (!leave_in_map)
		clear_fields(skel->maps.bss_A);

	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_push_pop_nested), &opts);
	ASSERT_OK(ret, "global_list_push_pop_nested");
	ASSERT_OK(opts.retval, "global_list_push_pop_nested retval");
	if (!leave_in_map)
		clear_fields(skel->maps.bss_A);

	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.global_list_array_push_pop), &opts);
	ASSERT_OK(ret, "global_list_array_push_pop");
	ASSERT_OK(opts.retval, "global_list_array_push_pop retval");
	if (!leave_in_map)
		clear_fields(skel->maps.bss_A);

	if (mode == PUSH_POP)
		goto end;

+42 −0
Original line number Diff line number Diff line
@@ -11,6 +11,22 @@

#include "linked_list.h"

struct head_nested_inner {
	struct bpf_spin_lock lock;
	struct bpf_list_head head __contains(foo, node2);
};

struct head_nested {
	int dummy;
	struct head_nested_inner inner;
};

private(C) struct bpf_spin_lock glock_c;
private(C) struct bpf_list_head ghead_array[2] __contains(foo, node2);
private(C) struct bpf_list_head ghead_array_one[1] __contains(foo, node2);

private(D) struct head_nested ghead_nested;

static __always_inline
int list_push_pop(struct bpf_spin_lock *lock, struct bpf_list_head *head, bool leave_in_map)
{
@@ -309,6 +325,32 @@ int global_list_push_pop(void *ctx)
	return test_list_push_pop(&glock, &ghead);
}

SEC("tc")
int global_list_push_pop_nested(void *ctx)
{
	return test_list_push_pop(&ghead_nested.inner.lock, &ghead_nested.inner.head);
}

SEC("tc")
int global_list_array_push_pop(void *ctx)
{
	int r;

	r = test_list_push_pop(&glock_c, &ghead_array[0]);
	if (r)
		return r;

	r = test_list_push_pop(&glock_c, &ghead_array[1]);
	if (r)
		return r;

	/* Arrays with only one element is a special case, being treated
	 * just like a bpf_list_head variable by the verifier, not an
	 * array.
	 */
	return test_list_push_pop(&glock_c, &ghead_array_one[0]);
}

SEC("tc")
int map_list_push_pop_multiple(void *ctx)
{