tools/testing/selftests/bpf/prog_tests/task_local_storage.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/task_local_storage.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/task_local_storage.c
Extension
.c
Size
14551 bytes
Lines
526
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			/* Only assert once here to avoid excessive
			 * PASS printing during test failure.
			 */
			ASSERT_OK(err, "pthread_create");
			waitall(tids, i);
			goto done;
		}
	}

	/* With 32 threads, 1s is enough to reproduce the issue */
	sleep(1);
	waitall(tids, nr_threads);

	info_len = sizeof(info);
	prog_fd = bpf_program__fd(skel->progs.socket_post_create);
	err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
	ASSERT_OK(err, "get prog info");
	ASSERT_EQ(info.recursion_misses, 0, "prog recursion");

	ASSERT_EQ(skel->bss->nr_get_errs, 0, "bpf_task_storage_get busy");
	ASSERT_EQ(skel->bss->nr_del_errs, 0, "bpf_task_storage_delete busy");

done:
	task_storage_nodeadlock__destroy(skel);
	sched_setaffinity(getpid(), sizeof(old), &old);
}

static struct user_data udata __attribute__((aligned(16))) = {
	.a = 1,
	.b = 2,
};

static struct user_data udata2 __attribute__((aligned(16))) = {
	.a = 3,
	.b = 4,
};

static void check_udata2(int expected)
{
	udata2.result = udata2.nested_result = 0;
	usleep(1);
	ASSERT_EQ(udata2.result, expected, "udata2.result");
	ASSERT_EQ(udata2.nested_result, expected, "udata2.nested_result");
}

static void test_uptr_basic(void)
{
	int map_fd, parent_task_fd, ev_fd;
	struct value_type value = {};
	struct task_ls_uptr *skel;
	pid_t child_pid, my_tid;
	__u64 ev_dummy_data = 1;
	int err;

	my_tid = sys_gettid();
	parent_task_fd = sys_pidfd_open(my_tid, 0);
	if (!ASSERT_OK_FD(parent_task_fd, "parent_task_fd"))
		return;

	ev_fd = eventfd(0, 0);
	if (!ASSERT_OK_FD(ev_fd, "ev_fd")) {
		close(parent_task_fd);
		return;
	}

	skel = task_ls_uptr__open_and_load();
	if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
		goto out;

	map_fd = bpf_map__fd(skel->maps.datamap);
	value.udata = &udata;
	value.nested.udata = &udata;
	err = bpf_map_update_elem(map_fd, &parent_task_fd, &value, BPF_NOEXIST);
	if (!ASSERT_OK(err, "update_elem(udata)"))
		goto out;

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

	child_pid = fork();
	if (!ASSERT_NEQ(child_pid, -1, "fork"))
		goto out;

	/* Call syscall in the child process, but access the map value of
	 * the parent process in the BPF program to check if the user kptr
	 * is translated/mapped correctly.
	 */
	if (child_pid == 0) {

Annotation

Implementation Notes