xref: /linux/tools/testing/selftests/bpf/prog_tests/exe_ctx.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2026 Valve Corporation.
4  * Author: Changwoo Min <changwoo@igalia.com>
5  */
6 
7 #include <test_progs.h>
8 #include <sys/syscall.h>
9 #include "test_ctx.skel.h"
10 
11 void test_exe_ctx(void)
12 {
13 	LIBBPF_OPTS(bpf_test_run_opts, opts);
14 	cpu_set_t old_cpuset, target_cpuset;
15 	struct test_ctx *skel;
16 	int err, prog_fd;
17 
18 	/* 1. Pin the current process to CPU 0. */
19 	if (sched_getaffinity(0, sizeof(old_cpuset), &old_cpuset) == 0) {
20 		CPU_ZERO(&target_cpuset);
21 		CPU_SET(0, &target_cpuset);
22 		ASSERT_OK(sched_setaffinity(0, sizeof(target_cpuset),
23 					    &target_cpuset), "setaffinity");
24 	}
25 
26 	skel = test_ctx__open_and_load();
27 	if (!ASSERT_OK_PTR(skel, "skel_load"))
28 		goto restore_affinity;
29 
30 	err = test_ctx__attach(skel);
31 	if (!ASSERT_OK(err, "skel_attach"))
32 		goto cleanup;
33 
34 	/* 2. When we run this, the kernel will execute the BPF prog on CPU 0. */
35 	prog_fd = bpf_program__fd(skel->progs.trigger_all_contexts);
36 	err = bpf_prog_test_run_opts(prog_fd, &opts);
37 	ASSERT_OK(err, "test_run_trigger");
38 
39 	/* 3. Wait for the local CPU's softirq/tasklet to finish. */
40 	for (int i = 0; i < 1000; i++) {
41 		if (skel->bss->count_task > 0 &&
42 		    skel->bss->count_hardirq > 0 &&
43 		    skel->bss->count_softirq > 0)
44 			break;
45 		usleep(1000); /* Wait 1ms per iteration, up to 1 sec total */
46 	}
47 
48 	/* On CPU 0, these should now all be non-zero. */
49 	ASSERT_GT(skel->bss->count_task, 0, "task_ok");
50 	ASSERT_GT(skel->bss->count_hardirq, 0, "hardirq_ok");
51 	ASSERT_GT(skel->bss->count_softirq, 0, "softirq_ok");
52 
53 cleanup:
54 	test_ctx__destroy(skel);
55 
56 restore_affinity:
57 	ASSERT_OK(sched_setaffinity(0, sizeof(old_cpuset), &old_cpuset),
58 		  "restore_affinity");
59 }
60