File Index
Files and directories
Sign in
FILE

res_spin_lock.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/res_spin_lock.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2024-2025 Meta Platforms, Inc. and affiliates. */
  3#include <test_progs.h>
  4#include <network_helpers.h>
  5#include <sys/sysinfo.h>
  6
  7#include "res_spin_lock.skel.h"
  8#include "res_spin_lock_fail.skel.h"
  9
 10void test_res_spin_lock_failure(void)
 11{
 12	RUN_TESTS(res_spin_lock_fail);
 13}
 14
 15static volatile int skip;
 16
 17static void *spin_lock_thread(void *arg)
 18{
 19	int err, prog_fd = *(u32 *) arg;
 20	LIBBPF_OPTS(bpf_test_run_opts, topts,
 21		.data_in = &pkt_v4,
 22		.data_size_in = sizeof(pkt_v4),
 23		.repeat = 10000,
 24	);
 25
 26	while (!READ_ONCE(skip)) {
 27		err = bpf_prog_test_run_opts(prog_fd, &topts);
 28		if (err || topts.retval) {
 29			ASSERT_OK(err, "test_run");
 30			ASSERT_OK(topts.retval, "test_run retval");
 31			break;
 32		}
 33	}
 34	pthread_exit(arg);
 35}
 36
 37void test_res_spin_lock_success(void)
 38{
 39	LIBBPF_OPTS(bpf_test_run_opts, topts,
 40		.data_in = &pkt_v4,
 41		.data_size_in = sizeof(pkt_v4),
 42		.repeat = 1,
 43	);
 44	struct res_spin_lock *skel;
 45	pthread_t thread_id[16];
 46	int prog_fd, i, err;
 47	void *ret;
 48
 49	if (get_nprocs() < 2) {
 50		test__skip();
 51		return;
 52	}
 53
 54	skel = res_spin_lock__open_and_load();
 55	if (!ASSERT_OK_PTR(skel, "res_spin_lock__open_and_load"))
 56		return;
 57	/* AA deadlock */
 58	prog_fd = bpf_program__fd(skel->progs.res_spin_lock_test);
 59	err = bpf_prog_test_run_opts(prog_fd, &topts);
 60	ASSERT_OK(err, "error");
 61	ASSERT_OK(topts.retval, "retval");
 62
 63	prog_fd = bpf_program__fd(skel->progs.res_spin_lock_test_held_lock_max);
 64	err = bpf_prog_test_run_opts(prog_fd, &topts);
 65	ASSERT_OK(err, "error");
 66	ASSERT_OK(topts.retval, "retval");
 67
 68	/* Multi-threaded ABBA deadlock. */
 69
 70	prog_fd = bpf_program__fd(skel->progs.res_spin_lock_test_AB);
 71	for (i = 0; i < 16; i++) {
 72		int err;
 73
 74		err = pthread_create(&thread_id[i], NULL, &spin_lock_thread, &prog_fd);
 75		if (!ASSERT_OK(err, "pthread_create"))
 76			goto end;
 77	}
 78
 79	topts.retval = 0;
 80	topts.repeat = 1000;
 81	int fd = bpf_program__fd(skel->progs.res_spin_lock_test_BA);
 82	while (!topts.retval && !err && !READ_ONCE(skel->bss->err)) {
 83		err = bpf_prog_test_run_opts(fd, &topts);
 84	}
 85
 86	WRITE_ONCE(skip, true);
 87
 88	for (i = 0; i < 16; i++) {
 89		if (!ASSERT_OK(pthread_join(thread_id[i], &ret), "pthread_join"))
 90			goto end;
 91		if (!ASSERT_EQ(ret, &prog_fd, "ret == prog_fd"))
 92			goto end;
 93	}
 94
 95	ASSERT_EQ(READ_ONCE(skel->bss->err), -EDEADLK, "timeout err");
 96	ASSERT_OK(err, "err");
 97	ASSERT_EQ(topts.retval, -EDEADLK, "timeout");
 98end:
 99	res_spin_lock__destroy(skel);
100	return;
101}
102
103void serial_test_res_spin_lock_stress(void)
104{
105	if (libbpf_num_possible_cpus() < 3) {
106		test__skip();
107		return;
108	}
109
110	ASSERT_OK(load_module("bpf_test_rqspinlock.ko", false), "load module AA");
111	sleep(5);
112	unload_module("bpf_test_rqspinlock", false);
113	/*
114	 * Insert bpf_test_rqspinlock.ko manually with test_mode=[1|2] to test
115	 * other cases (ABBA, ABBCCA).
116	 */
117}
~/ Read-only file preview.