Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
  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 = syscall(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.task_trusted_non_rcuptr, true);
 32	err = rcu_read_lock__load(skel);
 33	if (!ASSERT_OK(err, "skel_load"))
 34		goto out;
 35
 36	err = rcu_read_lock__attach(skel);
 37	if (!ASSERT_OK(err, "skel_attach"))
 38		goto out;
 39
 40	syscall(SYS_getpgid);
 41
 42	ASSERT_EQ(skel->bss->task_storage_val, 2, "task_storage_val");
 43	ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");
 44out:
 45	rcu_read_lock__destroy(skel);
 46}
 47
 48static void test_rcuptr_acquire(void)
 49{
 50	struct rcu_read_lock *skel;
 51	int err;
 52
 53	skel = rcu_read_lock__open();
 54	if (!ASSERT_OK_PTR(skel, "skel_open"))
 55		return;
 56
 57	skel->bss->target_pid = syscall(SYS_gettid);
 58
 59	bpf_program__set_autoload(skel->progs.task_acquire, true);
 60	err = rcu_read_lock__load(skel);
 61	if (!ASSERT_OK(err, "skel_load"))
 62		goto out;
 63
 64	err = rcu_read_lock__attach(skel);
 65	ASSERT_OK(err, "skel_attach");
 66out:
 67	rcu_read_lock__destroy(skel);
 68}
 69
 70static const char * const inproper_region_tests[] = {
 71	"miss_lock",
 72	"no_lock",
 73	"miss_unlock",
 74	"non_sleepable_rcu_mismatch",
 75	"inproper_sleepable_helper",
 76	"inproper_sleepable_kfunc",
 77	"nested_rcu_region",
 78};
 79
 80static void test_inproper_region(void)
 81{
 82	struct rcu_read_lock *skel;
 83	struct bpf_program *prog;
 84	int i, err;
 85
 86	for (i = 0; i < ARRAY_SIZE(inproper_region_tests); i++) {
 87		skel = rcu_read_lock__open();
 88		if (!ASSERT_OK_PTR(skel, "skel_open"))
 89			return;
 90
 91		prog = bpf_object__find_program_by_name(skel->obj, inproper_region_tests[i]);
 92		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
 93			goto out;
 94		bpf_program__set_autoload(prog, true);
 95		err = rcu_read_lock__load(skel);
 96		ASSERT_ERR(err, "skel_load");
 97out:
 98		rcu_read_lock__destroy(skel);
 99	}
100}
101
102static const char * const rcuptr_misuse_tests[] = {
103	"task_untrusted_rcuptr",
104	"cross_rcu_region",
105};
106
107static void test_rcuptr_misuse(void)
108{
109	struct rcu_read_lock *skel;
110	struct bpf_program *prog;
111	int i, err;
112
113	for (i = 0; i < ARRAY_SIZE(rcuptr_misuse_tests); i++) {
114		skel = rcu_read_lock__open();
115		if (!ASSERT_OK_PTR(skel, "skel_open"))
116			return;
117
118		prog = bpf_object__find_program_by_name(skel->obj, rcuptr_misuse_tests[i]);
119		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
120			goto out;
121		bpf_program__set_autoload(prog, true);
122		err = rcu_read_lock__load(skel);
123		ASSERT_ERR(err, "skel_load");
124out:
125		rcu_read_lock__destroy(skel);
126	}
127}
128
129void test_rcu_read_lock(void)
130{
131	int cgroup_fd;
132
133	cgroup_fd = test__join_cgroup("/rcu_read_lock");
134	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /rcu_read_lock"))
135		goto out;
136
137	cgroup_id = get_cgroup_id("/rcu_read_lock");
138	if (test__start_subtest("success"))
139		test_success();
140	if (test__start_subtest("rcuptr_acquire"))
141		test_rcuptr_acquire();
142	if (test__start_subtest("negative_tests_inproper_region"))
143		test_inproper_region();
144	if (test__start_subtest("negative_tests_rcuptr_misuse"))
145		test_rcuptr_misuse();
146	close(cgroup_fd);
147out:;
148}