kernel/bpf/arraymap.c

Source file repositories/reference/linux-study-clean/kernel/bpf/arraymap.c

File Facts

System
Linux kernel
Corpus path
kernel/bpf/arraymap.c
Extension
.c
Size
39836 bytes
Lines
1461
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bpf_iter_seq_array_map_info {
	struct bpf_map *map;
	void *percpu_value_buf;
	u32 index;
};

static void *bpf_array_map_seq_start(struct seq_file *seq, loff_t *pos)
{
	struct bpf_iter_seq_array_map_info *info = seq->private;
	struct bpf_map *map = info->map;
	struct bpf_array *array;
	u32 index;

	if (info->index >= map->max_entries)
		return NULL;

	if (*pos == 0)
		++*pos;
	array = container_of(map, struct bpf_array, map);
	index = info->index & array->index_mask;
	if (info->percpu_value_buf)
		return (void *)(uintptr_t)array->pptrs[index];
	return array_map_elem_ptr(array, index);
}

static void *bpf_array_map_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct bpf_iter_seq_array_map_info *info = seq->private;
	struct bpf_map *map = info->map;
	struct bpf_array *array;
	u32 index;

	++*pos;
	++info->index;
	if (info->index >= map->max_entries)
		return NULL;

	array = container_of(map, struct bpf_array, map);
	index = info->index & array->index_mask;
	if (info->percpu_value_buf)
		return (void *)(uintptr_t)array->pptrs[index];
	return array_map_elem_ptr(array, index);
}

static int __bpf_array_map_seq_show(struct seq_file *seq, void *v)
{
	struct bpf_iter_seq_array_map_info *info = seq->private;
	struct bpf_iter__bpf_map_elem ctx = {};
	struct bpf_map *map = info->map;
	struct bpf_array *array = container_of(map, struct bpf_array, map);
	struct bpf_iter_meta meta;
	struct bpf_prog *prog;
	int off = 0, cpu = 0;
	void __percpu *pptr;
	u32 size;

	meta.seq = seq;
	prog = bpf_iter_get_info(&meta, v == NULL);
	if (!prog)
		return 0;

	ctx.meta = &meta;
	ctx.map = info->map;
	if (v) {
		ctx.key = &info->index;

		if (!info->percpu_value_buf) {
			ctx.value = v;
		} else {
			pptr = (void __percpu *)(uintptr_t)v;
			size = array->elem_size;
			for_each_possible_cpu(cpu) {
				copy_map_value_long(map, info->percpu_value_buf + off,
						    per_cpu_ptr(pptr, cpu));
				check_and_init_map_value(map, info->percpu_value_buf + off);
				off += size;
			}
			ctx.value = info->percpu_value_buf;
		}
	}

	return bpf_iter_run_prog(prog, &ctx);
}

static int bpf_array_map_seq_show(struct seq_file *seq, void *v)
{
	return __bpf_array_map_seq_show(seq, v);
}

static void bpf_array_map_seq_stop(struct seq_file *seq, void *v)

Annotation

Implementation Notes