tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
Extension
.c
Size
7786 bytes
Lines
279
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 (is_pcpu) {
			for (j = 0; j < bpf_num_possible_cpus(); j++) {
				CHECK(keys[i] + 1 + j != bpf_percpu(v[i], j),
				      "key/value checking",
				      "error: i %d j %d key %d value %d\n",
				      i, j, keys[i], bpf_percpu(v[i],  j));
			}
		} else {
			CHECK(keys[i] + 1 != ((int *)values)[i],
			      "key/value checking",
			      "error: i %d key %d value %d\n", i, keys[i],
			      ((int *)values)[i]);
		}

		visited[i] = 1;

	}
	for (i = 0; i < max_entries; i++) {
		CHECK(visited[i] != 1, "visited checking",
		      "error: keys array at index %d missing\n", i);
	}
}

void __test_map_lookup_and_delete_batch(bool is_pcpu)
{
	__u32 batch, count, total, total_success;
	typedef BPF_DECLARE_PERCPU(int, value);
	int map_fd, *keys, *visited, key;
	const __u32 max_entries = 10;
	value pcpu_values[max_entries];
	int err, step, value_size;
	bool nospace_err;
	void *values;
	DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, opts,
		.elem_flags = 0,
		.flags = 0,
	);

	map_fd = bpf_map_create(is_pcpu ? BPF_MAP_TYPE_PERCPU_HASH : BPF_MAP_TYPE_HASH,
				"hash_map", sizeof(int), sizeof(int), max_entries, NULL);
	CHECK(map_fd == -1,
	      "bpf_map_create()", "error:%s\n", strerror(errno));

	value_size = is_pcpu ? sizeof(value) : sizeof(int);
	keys = malloc(max_entries * sizeof(int));
	if (is_pcpu)
		values = pcpu_values;
	else
		values = malloc(max_entries * sizeof(int));
	visited = malloc(max_entries * sizeof(int));
	CHECK(!keys || !values || !visited, "malloc()",
	      "error:%s\n", strerror(errno));

	/* test 1: lookup/delete an empty hash table, -ENOENT */
	count = max_entries;
	err = bpf_map_lookup_and_delete_batch(map_fd, NULL, &batch, keys,
					      values, &count, &opts);
	CHECK((err && errno != ENOENT), "empty map",
	      "error: %s\n", strerror(errno));

	/* populate elements to the map */
	map_batch_update(map_fd, max_entries, keys, values, is_pcpu);

	/* test 2: lookup/delete with count = 0, success */
	count = 0;
	err = bpf_map_lookup_and_delete_batch(map_fd, NULL, &batch, keys,
					      values, &count, &opts);
	CHECK(err, "count = 0", "error: %s\n", strerror(errno));

	/* test 3: lookup/delete with count = max_entries, success */
	memset(keys, 0, max_entries * sizeof(*keys));
	memset(values, 0, max_entries * value_size);
	count = max_entries;
	err = bpf_map_lookup_and_delete_batch(map_fd, NULL, &batch, keys,
					      values, &count, &opts);
	CHECK((err && errno != ENOENT), "count = max_entries",
	       "error: %s\n", strerror(errno));
	CHECK(count != max_entries, "count = max_entries",
	      "count = %u, max_entries = %u\n", count, max_entries);
	map_batch_verify(visited, max_entries, keys, values, is_pcpu);

	/* bpf_map_get_next_key() should return -ENOENT for an empty map. */
	err = bpf_map_get_next_key(map_fd, NULL, &key);
	CHECK(!err, "bpf_map_get_next_key()", "error: %s\n", strerror(errno));

	/* test 4: lookup/delete in a loop with various steps. */
	total_success = 0;
	for (step = 1; step < max_entries; step++) {
		map_batch_update(map_fd, max_entries, keys, values, is_pcpu);
		memset(keys, 0, max_entries * sizeof(*keys));

Annotation

Implementation Notes