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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/percpu_alloc.c
Extension
.c
Size
13736 bytes
Lines
464
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

static void test_failure(void) {
	RUN_TESTS(percpu_alloc_fail);
}

static void test_percpu_map_op_cpu_flag(struct bpf_map *map, void *keys, size_t key_sz, u32 entries,
					int nr_cpus, bool test_batch)
{
	size_t value_sz = sizeof(u32), value_sz_cpus, value_sz_total;
	u32 *values = NULL, *values_percpu = NULL;
	const u32 value = 0xDEADC0DE;
	int i, j, cpu, map_fd, err;
	u64 batch = 0, flags;
	void *values_row;
	u32 count, v;
	LIBBPF_OPTS(bpf_map_batch_opts, batch_opts);

	value_sz_cpus = value_sz * nr_cpus;
	values = calloc(entries, value_sz_cpus);
	if (!ASSERT_OK_PTR(values, "calloc values"))
		return;

	values_percpu = calloc(entries, roundup(value_sz, 8) * nr_cpus);
	if (!ASSERT_OK_PTR(values_percpu, "calloc values_percpu")) {
		free(values);
		return;
	}

	value_sz_total = value_sz_cpus * entries;
	memset(values, 0, value_sz_total);

	map_fd = bpf_map__fd(map);
	flags = BPF_F_CPU | BPF_F_ALL_CPUS;
	err = bpf_map_lookup_elem_flags(map_fd, keys, values, flags);
	if (!ASSERT_ERR(err, "bpf_map_lookup_elem_flags cpu|all_cpus"))
		goto out;

	err = bpf_map_update_elem(map_fd, keys, values, flags);
	if (!ASSERT_ERR(err, "bpf_map_update_elem cpu|all_cpus"))
		goto out;

	flags = BPF_F_ALL_CPUS;
	err = bpf_map_lookup_elem_flags(map_fd, keys, values, flags);
	if (!ASSERT_ERR(err, "bpf_map_lookup_elem_flags all_cpus"))
		goto out;

	flags = BPF_F_LOCK | BPF_F_CPU;
	err = bpf_map_lookup_elem_flags(map_fd, keys, values, flags);
	if (!ASSERT_ERR(err, "bpf_map_lookup_elem_flags BPF_F_LOCK"))
		goto out;

	flags = BPF_F_LOCK | BPF_F_ALL_CPUS;
	err = bpf_map_update_elem(map_fd, keys, values, flags);
	if (!ASSERT_ERR(err, "bpf_map_update_elem BPF_F_LOCK"))
		goto out;

	flags = (u64)nr_cpus << 32 | BPF_F_CPU;
	err = bpf_map_update_elem(map_fd, keys, values, flags);
	if (!ASSERT_EQ(err, -ERANGE, "bpf_map_update_elem -ERANGE"))
		goto out;

	err = bpf_map__update_elem(map, keys, key_sz, values, value_sz, flags);
	if (!ASSERT_EQ(err, -ERANGE, "bpf_map__update_elem -ERANGE"))
		goto out;

	err = bpf_map_lookup_elem_flags(map_fd, keys, values, flags);
	if (!ASSERT_EQ(err, -ERANGE, "bpf_map_lookup_elem_flags -ERANGE"))
		goto out;

	err = bpf_map__lookup_elem(map, keys, key_sz, values, value_sz, flags);
	if (!ASSERT_EQ(err, -ERANGE, "bpf_map__lookup_elem -ERANGE"))
		goto out;

	for (cpu = 0; cpu < nr_cpus; cpu++) {
		/* clear value on all cpus */
		values[0] = 0;
		flags = BPF_F_ALL_CPUS;
		for (i = 0; i < entries; i++) {
			err = bpf_map__update_elem(map, keys + i * key_sz, key_sz, values,
						   value_sz, flags);
			if (!ASSERT_OK(err, "bpf_map__update_elem all_cpus"))
				goto out;
		}

		/* update value on specified cpu */
		for (i = 0; i < entries; i++) {
			values[0] = value;
			flags = (u64)cpu << 32 | BPF_F_CPU;
			err = bpf_map__update_elem(map, keys + i * key_sz, key_sz, values,
						   value_sz, flags);
			if (!ASSERT_OK(err, "bpf_map__update_elem specified cpu"))

Annotation

Implementation Notes