xref: /linux/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
12dfc8186SKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
22dfc8186SKumar Kartikeya Dwivedi /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
32dfc8186SKumar Kartikeya Dwivedi #include <test_progs.h>
42dfc8186SKumar Kartikeya Dwivedi #include <network_helpers.h>
52dfc8186SKumar Kartikeya Dwivedi #include <sys/sysinfo.h>
62dfc8186SKumar Kartikeya Dwivedi 
7*1f375aefSKumar Kartikeya Dwivedi struct __qspinlock { int val; };
8*1f375aefSKumar Kartikeya Dwivedi typedef struct __qspinlock arena_spinlock_t;
92dfc8186SKumar Kartikeya Dwivedi 
102dfc8186SKumar Kartikeya Dwivedi struct arena_qnode {
112dfc8186SKumar Kartikeya Dwivedi 	unsigned long next;
122dfc8186SKumar Kartikeya Dwivedi 	int count;
132dfc8186SKumar Kartikeya Dwivedi 	int locked;
142dfc8186SKumar Kartikeya Dwivedi };
152dfc8186SKumar Kartikeya Dwivedi 
162dfc8186SKumar Kartikeya Dwivedi #include "arena_spin_lock.skel.h"
172dfc8186SKumar Kartikeya Dwivedi 
182dfc8186SKumar Kartikeya Dwivedi static long cpu;
192dfc8186SKumar Kartikeya Dwivedi static int repeat;
202dfc8186SKumar Kartikeya Dwivedi 
212dfc8186SKumar Kartikeya Dwivedi pthread_barrier_t barrier;
222dfc8186SKumar Kartikeya Dwivedi 
232dfc8186SKumar Kartikeya Dwivedi static void *spin_lock_thread(void *arg)
242dfc8186SKumar Kartikeya Dwivedi {
252dfc8186SKumar Kartikeya Dwivedi 	int err, prog_fd = *(u32 *)arg;
262dfc8186SKumar Kartikeya Dwivedi 	LIBBPF_OPTS(bpf_test_run_opts, topts,
272dfc8186SKumar Kartikeya Dwivedi 		.data_in = &pkt_v4,
282dfc8186SKumar Kartikeya Dwivedi 		.data_size_in = sizeof(pkt_v4),
292dfc8186SKumar Kartikeya Dwivedi 		.repeat = repeat,
302dfc8186SKumar Kartikeya Dwivedi 	);
312dfc8186SKumar Kartikeya Dwivedi 	cpu_set_t cpuset;
322dfc8186SKumar Kartikeya Dwivedi 
332dfc8186SKumar Kartikeya Dwivedi 	CPU_ZERO(&cpuset);
342dfc8186SKumar Kartikeya Dwivedi 	CPU_SET(__sync_fetch_and_add(&cpu, 1), &cpuset);
352dfc8186SKumar Kartikeya Dwivedi 	ASSERT_OK(pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset), "cpu affinity");
362dfc8186SKumar Kartikeya Dwivedi 
372dfc8186SKumar Kartikeya Dwivedi 	err = pthread_barrier_wait(&barrier);
382dfc8186SKumar Kartikeya Dwivedi 	if (err != PTHREAD_BARRIER_SERIAL_THREAD && err != 0)
392dfc8186SKumar Kartikeya Dwivedi 		ASSERT_FALSE(true, "pthread_barrier");
402dfc8186SKumar Kartikeya Dwivedi 
412dfc8186SKumar Kartikeya Dwivedi 	err = bpf_prog_test_run_opts(prog_fd, &topts);
422dfc8186SKumar Kartikeya Dwivedi 	ASSERT_OK(err, "test_run err");
432dfc8186SKumar Kartikeya Dwivedi 	ASSERT_EQ((int)topts.retval, 0, "test_run retval");
442dfc8186SKumar Kartikeya Dwivedi 
452dfc8186SKumar Kartikeya Dwivedi 	pthread_exit(arg);
462dfc8186SKumar Kartikeya Dwivedi }
472dfc8186SKumar Kartikeya Dwivedi 
482dfc8186SKumar Kartikeya Dwivedi static void test_arena_spin_lock_size(int size)
492dfc8186SKumar Kartikeya Dwivedi {
502dfc8186SKumar Kartikeya Dwivedi 	LIBBPF_OPTS(bpf_test_run_opts, topts);
512dfc8186SKumar Kartikeya Dwivedi 	struct arena_spin_lock *skel;
522dfc8186SKumar Kartikeya Dwivedi 	pthread_t thread_id[16];
532dfc8186SKumar Kartikeya Dwivedi 	int prog_fd, i, err;
542dfc8186SKumar Kartikeya Dwivedi 	void *ret;
552dfc8186SKumar Kartikeya Dwivedi 
562dfc8186SKumar Kartikeya Dwivedi 	if (get_nprocs() < 2) {
572dfc8186SKumar Kartikeya Dwivedi 		test__skip();
582dfc8186SKumar Kartikeya Dwivedi 		return;
592dfc8186SKumar Kartikeya Dwivedi 	}
602dfc8186SKumar Kartikeya Dwivedi 
612dfc8186SKumar Kartikeya Dwivedi 	skel = arena_spin_lock__open_and_load();
622dfc8186SKumar Kartikeya Dwivedi 	if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open_and_load"))
632dfc8186SKumar Kartikeya Dwivedi 		return;
642dfc8186SKumar Kartikeya Dwivedi 	if (skel->data->test_skip == 2) {
652dfc8186SKumar Kartikeya Dwivedi 		test__skip();
662dfc8186SKumar Kartikeya Dwivedi 		goto end;
672dfc8186SKumar Kartikeya Dwivedi 	}
682dfc8186SKumar Kartikeya Dwivedi 	skel->bss->cs_count = size;
692dfc8186SKumar Kartikeya Dwivedi 	skel->bss->limit = repeat * 16;
702dfc8186SKumar Kartikeya Dwivedi 
712dfc8186SKumar Kartikeya Dwivedi 	ASSERT_OK(pthread_barrier_init(&barrier, NULL, 16), "barrier init");
722dfc8186SKumar Kartikeya Dwivedi 
732dfc8186SKumar Kartikeya Dwivedi 	prog_fd = bpf_program__fd(skel->progs.prog);
742dfc8186SKumar Kartikeya Dwivedi 	for (i = 0; i < 16; i++) {
752dfc8186SKumar Kartikeya Dwivedi 		err = pthread_create(&thread_id[i], NULL, &spin_lock_thread, &prog_fd);
762dfc8186SKumar Kartikeya Dwivedi 		if (!ASSERT_OK(err, "pthread_create"))
772dfc8186SKumar Kartikeya Dwivedi 			goto end_barrier;
782dfc8186SKumar Kartikeya Dwivedi 	}
792dfc8186SKumar Kartikeya Dwivedi 
802dfc8186SKumar Kartikeya Dwivedi 	for (i = 0; i < 16; i++) {
812dfc8186SKumar Kartikeya Dwivedi 		if (!ASSERT_OK(pthread_join(thread_id[i], &ret), "pthread_join"))
822dfc8186SKumar Kartikeya Dwivedi 			goto end_barrier;
832dfc8186SKumar Kartikeya Dwivedi 		if (!ASSERT_EQ(ret, &prog_fd, "ret == prog_fd"))
842dfc8186SKumar Kartikeya Dwivedi 			goto end_barrier;
852dfc8186SKumar Kartikeya Dwivedi 	}
862dfc8186SKumar Kartikeya Dwivedi 
872dfc8186SKumar Kartikeya Dwivedi 	ASSERT_EQ(skel->bss->counter, repeat * 16, "check counter value");
882dfc8186SKumar Kartikeya Dwivedi 
892dfc8186SKumar Kartikeya Dwivedi end_barrier:
902dfc8186SKumar Kartikeya Dwivedi 	pthread_barrier_destroy(&barrier);
912dfc8186SKumar Kartikeya Dwivedi end:
922dfc8186SKumar Kartikeya Dwivedi 	arena_spin_lock__destroy(skel);
932dfc8186SKumar Kartikeya Dwivedi 	return;
942dfc8186SKumar Kartikeya Dwivedi }
952dfc8186SKumar Kartikeya Dwivedi 
962dfc8186SKumar Kartikeya Dwivedi void test_arena_spin_lock(void)
972dfc8186SKumar Kartikeya Dwivedi {
982dfc8186SKumar Kartikeya Dwivedi 	repeat = 1000;
992dfc8186SKumar Kartikeya Dwivedi 	if (test__start_subtest("arena_spin_lock_1"))
1002dfc8186SKumar Kartikeya Dwivedi 		test_arena_spin_lock_size(1);
1012dfc8186SKumar Kartikeya Dwivedi 	cpu = 0;
1022dfc8186SKumar Kartikeya Dwivedi 	if (test__start_subtest("arena_spin_lock_1000"))
1032dfc8186SKumar Kartikeya Dwivedi 		test_arena_spin_lock_size(1000);
1042dfc8186SKumar Kartikeya Dwivedi 	cpu = 0;
1052dfc8186SKumar Kartikeya Dwivedi 	repeat = 100;
1062dfc8186SKumar Kartikeya Dwivedi 	if (test__start_subtest("arena_spin_lock_50000"))
1072dfc8186SKumar Kartikeya Dwivedi 		test_arena_spin_lock_size(50000);
1082dfc8186SKumar Kartikeya Dwivedi }
109