Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ed8ec52 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by David S. Miller
Browse files

cgroup: bpf: Add BPF_MAP_TYPE_CGROUP_ARRAY



Add a BPF_MAP_TYPE_CGROUP_ARRAY and its bpf_map_ops's implementations.
To update an element, the caller is expected to obtain a cgroup2 backed
fd by open(cgroup2_dir) and then update the array with that fd.

Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Tejun Heo <tj@kernel.org>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1f3fe7eb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ enum bpf_map_type {
	BPF_MAP_TYPE_PERCPU_HASH,
	BPF_MAP_TYPE_PERCPU_ARRAY,
	BPF_MAP_TYPE_STACK_TRACE,
	BPF_MAP_TYPE_CGROUP_ARRAY,
};

enum bpf_prog_type {
+43 −0
Original line number Diff line number Diff line
@@ -537,3 +537,46 @@ static int __init register_perf_event_array_map(void)
	return 0;
}
late_initcall(register_perf_event_array_map);

#ifdef CONFIG_SOCK_CGROUP_DATA
static void *cgroup_fd_array_get_ptr(struct bpf_map *map,
				     struct file *map_file /* not used */,
				     int fd)
{
	return cgroup_get_from_fd(fd);
}

static void cgroup_fd_array_put_ptr(void *ptr)
{
	/* cgroup_put free cgrp after a rcu grace period */
	cgroup_put(ptr);
}

static void cgroup_fd_array_free(struct bpf_map *map)
{
	bpf_fd_array_map_clear(map);
	fd_array_map_free(map);
}

static const struct bpf_map_ops cgroup_array_ops = {
	.map_alloc = fd_array_map_alloc,
	.map_free = cgroup_fd_array_free,
	.map_get_next_key = array_map_get_next_key,
	.map_lookup_elem = fd_array_map_lookup_elem,
	.map_delete_elem = fd_array_map_delete_elem,
	.map_fd_get_ptr = cgroup_fd_array_get_ptr,
	.map_fd_put_ptr = cgroup_fd_array_put_ptr,
};

static struct bpf_map_type_list cgroup_array_type __read_mostly = {
	.ops = &cgroup_array_ops,
	.type = BPF_MAP_TYPE_CGROUP_ARRAY,
};

static int __init register_cgroup_array_map(void)
{
	bpf_register_map_type(&cgroup_array_type);
	return 0;
}
late_initcall(register_cgroup_array_map);
#endif
+2 −1
Original line number Diff line number Diff line
@@ -393,7 +393,8 @@ static int map_update_elem(union bpf_attr *attr)
	} else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
		err = bpf_percpu_array_update(map, key, value, attr->flags);
	} else if (map->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
		   map->map_type == BPF_MAP_TYPE_PROG_ARRAY) {
		   map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
		   map->map_type == BPF_MAP_TYPE_CGROUP_ARRAY) {
		rcu_read_lock();
		err = bpf_fd_array_map_update_elem(map, f.file, key, value,
						   attr->flags);
+2 −0
Original line number Diff line number Diff line
@@ -1035,6 +1035,8 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)
		if (func_id != BPF_FUNC_get_stackid)
			goto error;
		break;
	case BPF_MAP_TYPE_CGROUP_ARRAY:
		goto error;
	default:
		break;
	}