Commit 406c557e authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by Daniel Borkmann
Browse files

selftest/bpf: Add a recursion test



Add recursive non-sleepable fentry program as a test.
All attach points where sleepable progs can execute are non recursive so far.
The recursion protection mechanism for sleepable cannot be activated yet.

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210210033634.62081-6-alexei.starovoitov@gmail.com
parent ca06f55b
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021 Facebook */
#include <test_progs.h>
#include "recursion.skel.h"

void test_recursion(void)
{
	struct recursion *skel;
	int key = 0;
	int err;

	skel = recursion__open_and_load();
	if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
		return;

	err = recursion__attach(skel);
	if (!ASSERT_OK(err, "skel_attach"))
		goto out;

	ASSERT_EQ(skel->bss->pass1, 0, "pass1 == 0");
	bpf_map_lookup_elem(bpf_map__fd(skel->maps.hash1), &key, 0);
	ASSERT_EQ(skel->bss->pass1, 1, "pass1 == 1");
	bpf_map_lookup_elem(bpf_map__fd(skel->maps.hash1), &key, 0);
	ASSERT_EQ(skel->bss->pass1, 2, "pass1 == 2");

	ASSERT_EQ(skel->bss->pass2, 0, "pass2 == 0");
	bpf_map_lookup_elem(bpf_map__fd(skel->maps.hash2), &key, 0);
	ASSERT_EQ(skel->bss->pass2, 1, "pass2 == 1");
	bpf_map_lookup_elem(bpf_map__fd(skel->maps.hash2), &key, 0);
	ASSERT_EQ(skel->bss->pass2, 2, "pass2 == 2");
out:
	recursion__destroy(skel);
}
+46 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021 Facebook */

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

char _license[] SEC("license") = "GPL";

struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__uint(max_entries, 1);
	__type(key, int);
	__type(value, long);
} hash1 SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__uint(max_entries, 1);
	__type(key, int);
	__type(value, long);
} hash2 SEC(".maps");

int pass1 = 0;
int pass2 = 0;

SEC("fentry/__htab_map_lookup_elem")
int BPF_PROG(on_lookup, struct bpf_map *map)
{
	int key = 0;

	if (map == (void *)&hash1) {
		pass1++;
		return 0;
	}
	if (map == (void *)&hash2) {
		pass2++;
		/* htab_map_gen_lookup() will inline below call
		 * into direct call to __htab_map_lookup_elem()
		 */
		bpf_map_lookup_elem(&hash2, &key);
		return 0;
	}

	return 0;
}