File Index
Files and directories
Sign in
FILE

rcu_read_lock.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/rcu_read_lock.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.*/
  3
  4#define _GNU_SOURCE
  5#include <unistd.h>
  6#include <sys/syscall.h>
  7#include <sys/types.h>
  8#include <test_progs.h>
  9#include <bpf/btf.h>
 10#include "rcu_read_lock.skel.h"
 11#include "cgroup_helpers.h"
 12
 13static unsigned long long cgroup_id;
 14
 15static void test_success(void)
 16{
 17	struct rcu_read_lock *skel;
 18	int err;
 19
 20	skel = rcu_read_lock__open();
 21	if (!ASSERT_OK_PTR(skel, "skel_open"))
 22		return;
 23
 24	skel->bss->target_pid = sys_gettid();
 25
 26	bpf_program__set_autoload(skel->progs.get_cgroup_id, true);
 27	bpf_program__set_autoload(skel->progs.task_succ, true);
 28	bpf_program__set_autoload(skel->progs.two_regions, true);
 29	bpf_program__set_autoload(skel->progs.non_sleepable_1, true);
 30	bpf_program__set_autoload(skel->progs.non_sleepable_2, true);
 31	bpf_program__set_autoload(skel->progs.nested_rcu_region, true);
 32	bpf_program__set_autoload(skel->progs.task_trusted_non_rcuptr, true);
 33	bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog, true);
 34	bpf_program__set_autoload(skel->progs.rcu_read_lock_global_subprog, true);
 35	bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog_lock, true);
 36	bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog_unlock, true);
 37	err = rcu_read_lock__load(skel);
 38	if (!ASSERT_OK(err, "skel_load"))
 39		goto out;
 40
 41	err = rcu_read_lock__attach(skel);
 42	if (!ASSERT_OK(err, "skel_attach"))
 43		goto out;
 44
 45	syscall(SYS_getpgid);
 46
 47	ASSERT_EQ(skel->bss->task_storage_val, 2, "task_storage_val");
 48	ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");
 49out:
 50	rcu_read_lock__destroy(skel);
 51}
 52
 53static void test_rcuptr_acquire(void)
 54{
 55	struct rcu_read_lock *skel;
 56	int err;
 57
 58	skel = rcu_read_lock__open();
 59	if (!ASSERT_OK_PTR(skel, "skel_open"))
 60		return;
 61
 62	skel->bss->target_pid = sys_gettid();
 63
 64	bpf_program__set_autoload(skel->progs.task_acquire, true);
 65	err = rcu_read_lock__load(skel);
 66	if (!ASSERT_OK(err, "skel_load"))
 67		goto out;
 68
 69	err = rcu_read_lock__attach(skel);
 70	ASSERT_OK(err, "skel_attach");
 71out:
 72	rcu_read_lock__destroy(skel);
 73}
 74
 75static const char * const inproper_region_tests[] = {
 76	"miss_lock",
 77	"no_lock",
 78	"miss_unlock",
 79	"non_sleepable_rcu_mismatch",
 80	"inproper_sleepable_helper",
 81	"inproper_sleepable_kfunc",
 82	"nested_rcu_region_unbalanced_1",
 83	"nested_rcu_region_unbalanced_2",
 84	"rcu_read_lock_global_subprog_lock",
 85	"rcu_read_lock_global_subprog_unlock",
 86	"rcu_read_lock_sleepable_helper_global_subprog",
 87	"rcu_read_lock_sleepable_kfunc_global_subprog",
 88	"rcu_read_lock_sleepable_global_subprog_indirect",
 89};
 90
 91static void test_inproper_region(void)
 92{
 93	struct rcu_read_lock *skel;
 94	struct bpf_program *prog;
 95	int i, err;
 96
 97	for (i = 0; i < ARRAY_SIZE(inproper_region_tests); i++) {
 98		skel = rcu_read_lock__open();
 99		if (!ASSERT_OK_PTR(skel, "skel_open"))
100			return;
101
102		prog = bpf_object__find_program_by_name(skel->obj, inproper_region_tests[i]);
103		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
104			goto out;
105		bpf_program__set_autoload(prog, true);
106		err = rcu_read_lock__load(skel);
107		ASSERT_ERR(err, "skel_load");
108out:
109		rcu_read_lock__destroy(skel);
110	}
111}
112
113static const char * const rcuptr_misuse_tests[] = {
114	"task_untrusted_rcuptr",
115	"cross_rcu_region",
116};
117
118static void test_rcuptr_misuse(void)
119{
120	struct rcu_read_lock *skel;
121	struct bpf_program *prog;
122	int i, err;
123
124	for (i = 0; i < ARRAY_SIZE(rcuptr_misuse_tests); i++) {
125		skel = rcu_read_lock__open();
126		if (!ASSERT_OK_PTR(skel, "skel_open"))
127			return;
128
129		prog = bpf_object__find_program_by_name(skel->obj, rcuptr_misuse_tests[i]);
130		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
131			goto out;
132		bpf_program__set_autoload(prog, true);
133		err = rcu_read_lock__load(skel);
134		ASSERT_ERR(err, "skel_load");
135out:
136		rcu_read_lock__destroy(skel);
137	}
138}
139
140void test_rcu_read_lock(void)
141{
142	int cgroup_fd;
143
144	cgroup_fd = test__join_cgroup("/rcu_read_lock");
145	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /rcu_read_lock"))
146		goto out;
147
148	cgroup_id = get_cgroup_id("/rcu_read_lock");
149	if (test__start_subtest("success"))
150		test_success();
151	if (test__start_subtest("rcuptr_acquire"))
152		test_rcuptr_acquire();
153	if (test__start_subtest("negative_tests_inproper_region"))
154		test_inproper_region();
155	if (test__start_subtest("negative_tests_rcuptr_misuse"))
156		test_rcuptr_misuse();
157	close(cgroup_fd);
158out:;
159}
~/ Read-only file preview.