Commit 7fe74b43 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann
Browse files

libbpf: Make global data internal arrays mmap()-able, if possible



Add detection of BPF_F_MMAPABLE flag support for arrays and add it as an extra
flag to internal global data maps, if supported by kernel. This allows users
to memory-map global data and use it without BPF map operations, greatly
simplifying user experience.

Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarSong Liu <songliubraving@fb.com>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20191117172806.2195367-5-andriin@fb.com
parent fc970227
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -142,6 +142,8 @@ struct bpf_capabilities {
	__u32 btf_func:1;
	/* BTF_KIND_VAR and BTF_KIND_DATASEC support */
	__u32 btf_datasec:1;
	/* BPF_F_MMAPABLE is supported for arrays */
	__u32 array_mmap:1;
};

/*
@@ -857,8 +859,6 @@ bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type,
		pr_warn("failed to alloc map name\n");
		return -ENOMEM;
	}
	pr_debug("map '%s' (global data): at sec_idx %d, offset %zu.\n",
		 map_name, map->sec_idx, map->sec_offset);

	def = &map->def;
	def->type = BPF_MAP_TYPE_ARRAY;
@@ -866,6 +866,12 @@ bpf_object__init_internal_map(struct bpf_object *obj, enum libbpf_map_type type,
	def->value_size = data->d_size;
	def->max_entries = 1;
	def->map_flags = type == LIBBPF_MAP_RODATA ? BPF_F_RDONLY_PROG : 0;
	if (obj->caps.array_mmap)
		def->map_flags |= BPF_F_MMAPABLE;

	pr_debug("map '%s' (global data): at sec_idx %d, offset %zu, flags %x.\n",
		 map_name, map->sec_idx, map->sec_offset, def->map_flags);

	if (data_buff) {
		*data_buff = malloc(data->d_size);
		if (!*data_buff) {
@@ -2161,6 +2167,27 @@ static int bpf_object__probe_btf_datasec(struct bpf_object *obj)
	return 0;
}

static int bpf_object__probe_array_mmap(struct bpf_object *obj)
{
	struct bpf_create_map_attr attr = {
		.map_type = BPF_MAP_TYPE_ARRAY,
		.map_flags = BPF_F_MMAPABLE,
		.key_size = sizeof(int),
		.value_size = sizeof(int),
		.max_entries = 1,
	};
	int fd;

	fd = bpf_create_map_xattr(&attr);
	if (fd >= 0) {
		obj->caps.array_mmap = 1;
		close(fd);
		return 1;
	}

	return 0;
}

static int
bpf_object__probe_caps(struct bpf_object *obj)
{
@@ -2169,6 +2196,7 @@ bpf_object__probe_caps(struct bpf_object *obj)
		bpf_object__probe_global_data,
		bpf_object__probe_btf_func,
		bpf_object__probe_btf_datasec,
		bpf_object__probe_array_mmap,
	};
	int i, ret;