Skip to content

Commit ca2f339

Browse files
committed
selftests/bpf: Add tests for qspinlock in BPF arena
Add some basic selftests for qspinlock built over BPF arena using cond_break. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
1 parent 390b753 commit ca2f339

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3+
#include <test_progs.h>
4+
#include <network_helpers.h>
5+
6+
struct qspinlock { int val; };
7+
8+
#include "arena_spin_lock.skel.h"
9+
10+
static volatile int skip;
11+
static long cpu;
12+
int *counter;
13+
14+
static void *spin_lock_thread(void *arg)
15+
{
16+
int err, prog_fd = *(u32 *) arg;
17+
LIBBPF_OPTS(bpf_test_run_opts, topts,
18+
.data_in = &pkt_v4,
19+
.data_size_in = sizeof(pkt_v4),
20+
.repeat = 1,
21+
);
22+
cpu_set_t cpuset;
23+
24+
CPU_ZERO(&cpuset);
25+
CPU_SET(__sync_fetch_and_add(&cpu, 1), &cpuset);
26+
ASSERT_OK(pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset), "cpu affinity");
27+
28+
while (*READ_ONCE(counter) <= 50) {
29+
err = bpf_prog_test_run_opts(prog_fd, &topts);
30+
ASSERT_OK(err, "test_run err");
31+
ASSERT_EQ(topts.retval, 1, "test_run retval");
32+
}
33+
pthread_exit(arg);
34+
}
35+
36+
void test_arena_spin_lock(void)
37+
{
38+
struct arena_spin_lock *skel;
39+
pthread_t thread_id[16];
40+
int prog_fd, i, err;
41+
void *ret;
42+
43+
skel = arena_spin_lock__open_and_load();
44+
if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open_and_load"))
45+
return;
46+
counter = &skel->bss->counter;
47+
48+
prog_fd = bpf_program__fd(skel->progs.prog);
49+
for (i = 0; i < 16; i++) {
50+
err = pthread_create(&thread_id[i], NULL, &spin_lock_thread, &prog_fd);
51+
if (!ASSERT_OK(err, "pthread_create"))
52+
goto end;
53+
}
54+
55+
for (i = 0; i < 16; i++) {
56+
if (!ASSERT_OK(pthread_join(thread_id[i], &ret), "pthread_join"))
57+
goto end;
58+
if (!ASSERT_EQ(ret, &prog_fd, "ret == prog_fd"))
59+
goto end;
60+
}
61+
end:
62+
arena_spin_lock__destroy(skel);
63+
return;
64+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3+
#include <vmlinux.h>
4+
#include <bpf/bpf_tracing.h>
5+
#include <bpf/bpf_helpers.h>
6+
#include "bpf_misc.h"
7+
#include "bpf_arena_qspinlock.h"
8+
9+
struct {
10+
__uint(type, BPF_MAP_TYPE_ARENA);
11+
__uint(map_flags, BPF_F_MMAPABLE);
12+
__uint(max_entries, 100); /* number of pages */
13+
#ifdef __TARGET_ARCH_arm64
14+
__ulong(map_extra, 0x1ull << 32); /* start of mmap() region */
15+
#else
16+
__ulong(map_extra, 0x1ull << 44); /* start of mmap() region */
17+
#endif
18+
} arena SEC(".maps");
19+
20+
#if defined(ENABLE_ATOMICS_TESTS) && defined(__BPF_FEATURE_ADDR_SPACE_CAST)
21+
struct qspinlock __arena *lock;
22+
void *ptr;
23+
#endif
24+
25+
int counter;
26+
27+
SEC("tc")
28+
int prog(void *ctx)
29+
{
30+
bool ret = false;
31+
32+
#if defined(ENABLE_ATOMICS_TESTS) && defined(__BPF_FEATURE_ADDR_SPACE_CAST)
33+
ptr = &arena;
34+
bpf_preempt_disable();
35+
if (queued_spin_lock(lock))
36+
return false;
37+
WRITE_ONCE(counter, READ_ONCE(counter) + 1);
38+
bpf_repeat(BPF_MAX_LOOPS);
39+
ret = true;
40+
queued_spin_unlock(lock);
41+
bpf_preempt_enable();
42+
#endif
43+
return ret;
44+
}
45+
46+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)