From: Quentin Monnet <quentin@isovalent.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Cc: daniel@iogearbox.net, andrii@kernel.org,
torvalds@linux-foundation.org, brho@google.com,
hannes@cmpxchg.org, akpm@linux-foundation.org, urezki@gmail.com,
hch@infradead.org, linux-mm@kvack.org, kernel-team@fb.com
Subject: Re: [PATCH v3 bpf-next 10/14] libbpf: Recognize __arena global varaibles.
Date: Mon, 11 Mar 2024 17:09:01 +0000 [thread overview]
Message-ID: <aa2bdd2d-4c85-4b64-ba77-7da0df4f4660@isovalent.com> (raw)
In-Reply-To: <20240308010812.89848-11-alexei.starovoitov@gmail.com>
2024-03-08 01:08 UTC+0000 ~ Alexei Starovoitov
<alexei.starovoitov@gmail.com>
> From: Andrii Nakryiko <andrii@kernel.org>
>
> LLVM automatically places __arena variables into ".arena.1" ELF section.
> In order to use such global variables bpf program must include definition
> of arena map in ".maps" section, like:
> struct {
> __uint(type, BPF_MAP_TYPE_ARENA);
> __uint(map_flags, BPF_F_MMAPABLE);
> __uint(max_entries, 1000); /* number of pages */
> __ulong(map_extra, 2ull << 44); /* start of mmap() region */
> } arena SEC(".maps");
>
> libbpf recognizes both uses of arena and creates single `struct bpf_map *`
> instance in libbpf APIs.
> ".arena.1" ELF section data is used as initial data image, which is exposed
> through skeleton and bpf_map__initial_value() to the user, if they need to tune
> it before the load phase. During load phase, this initial image is copied over
> into mmap()'ed region corresponding to arena, and discarded.
>
> Few small checks here and there had to be added to make sure this
> approach works with bpf_map__initial_value(), mostly due to hard-coded
> assumption that map->mmaped is set up with mmap() syscall and should be
> munmap()'ed. For arena, .arena.1 can be (much) smaller than maximum
> arena size, so this smaller data size has to be tracked separately.
> Given it is enforced that there is only one arena for entire bpf_object
> instance, we just keep it in a separate field. This can be generalized
> if necessary later.
>
> All global variables from ".arena.1" section are accessible from user space
> via skel->arena->name_of_var.
>
> For bss/data/rodata the skeleton/libbpf perform the following sequence:
> 1. addr = mmap(MAP_ANONYMOUS)
> 2. user space optionally modifies global vars
> 3. map_fd = bpf_create_map()
> 4. bpf_update_map_elem(map_fd, addr) // to store values into the kernel
> 5. mmap(addr, MAP_FIXED, map_fd)
> after step 5 user spaces see the values it wrote at step 2 at the same addresses
>
> arena doesn't support update_map_elem. Hence skeleton/libbpf do:
> 1. addr = malloc(sizeof SEC ".arena.1")
> 2. user space optionally modifies global vars
> 3. map_fd = bpf_create_map(MAP_TYPE_ARENA)
> 4. real_addr = mmap(map->map_extra, MAP_SHARED | MAP_FIXED, map_fd)
> 5. memcpy(real_addr, addr) // this will fault-in and allocate pages
>
> At the end look and feel of global data vs __arena global data is the same from
> bpf prog pov.
>
> Another complication is:
> struct {
> __uint(type, BPF_MAP_TYPE_ARENA);
> } arena SEC(".maps");
>
> int __arena foo;
> int bar;
>
> ptr1 = &foo; // relocation against ".arena.1" section
> ptr2 = &arena; // relocation against ".maps" section
> ptr3 = &bar; // relocation against ".bss" section
>
> Fo the kernel ptr1 and ptr2 has point to the same arena's map_fd
> while ptr3 points to a different global array's map_fd.
> For the verifier:
> ptr1->type == unknown_scalar
> ptr2->type == const_ptr_to_map
> ptr3->type == ptr_to_map_value
>
> After verification, from JIT pov all 3 ptr-s are normal ld_imm64 insns.
>
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> ---
> tools/bpf/bpftool/gen.c | 13 +++++
> tools/lib/bpf/libbpf.c | 118 ++++++++++++++++++++++++++++++++++++----
> tools/lib/bpf/libbpf.h | 2 +-
> 3 files changed, 120 insertions(+), 13 deletions(-)
>
> diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
> index a3d72be347b0..4fa4ade1ce74 100644
> --- a/tools/bpf/bpftool/gen.c
> +++ b/tools/bpf/bpftool/gen.c
> @@ -120,6 +120,12 @@ static bool get_datasec_ident(const char *sec_name, char *buf, size_t buf_sz)
> static const char *pfxs[] = { ".data", ".rodata", ".bss", ".kconfig" };
> int i, n;
>
> + /* recognize hard coded LLVM section name */
> + if (strcmp(sec_name, ".arena.1") == 0) {
> + /* this is the name to use in skeleton */
> + snprintf(buf, buf_sz, "arena");
> + return true;
> + }
> for (i = 0, n = ARRAY_SIZE(pfxs); i < n; i++) {
> const char *pfx = pfxs[i];
>
> @@ -250,6 +256,13 @@ static const struct btf_type *find_type_for_map(struct btf *btf, const char *map
>
> static bool is_mmapable_map(const struct bpf_map *map, char *buf, size_t sz)
> {
> + size_t tmp_sz;
> +
> + if (bpf_map__type(map) == BPF_MAP_TYPE_ARENA && bpf_map__initial_value(map, &tmp_sz)) {
> + snprintf(buf, sz, "arena");
> + return true;
> + }
> +
> if (!bpf_map__is_internal(map) || !(bpf_map__map_flags(map) & BPF_F_MMAPABLE))
> return false;
>
For the bpftool changes:
Acked-by: Quentin Monnet <quentin@isovalent.com>
next prev parent reply other threads:[~2024-03-11 17:09 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-08 1:07 [PATCH v3 bpf-next 00/14] bpf: Introduce BPF arena Alexei Starovoitov
2024-03-08 1:07 ` [PATCH v3 bpf-next 01/14] bpf: Introduce bpf_arena Alexei Starovoitov
2024-03-11 22:01 ` Andrii Nakryiko
2024-03-11 22:41 ` Alexei Starovoitov
2024-03-11 22:59 ` Andrii Nakryiko
2024-03-12 0:47 ` Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 02/14] bpf: Disasm support for addr_space_cast instruction Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 03/14] bpf: Add x86-64 JIT support for PROBE_MEM32 pseudo instructions Alexei Starovoitov
2024-03-11 22:05 ` Andrii Nakryiko
2024-03-11 22:44 ` Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 04/14] bpf: Add x86-64 JIT support for bpf_addr_space_cast instruction Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 05/14] bpf: Recognize addr_space_cast instruction in the verifier Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 06/14] bpf: Recognize btf_decl_tag("arg:arena") as PTR_TO_ARENA Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 07/14] libbpf: Add __arg_arena to bpf_helpers.h Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 08/14] libbpf: Add support for bpf_arena Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 09/14] bpftool: Recognize arena map type Alexei Starovoitov
2024-03-11 17:08 ` Quentin Monnet
2024-03-08 1:08 ` [PATCH v3 bpf-next 10/14] libbpf: Recognize __arena global varaibles Alexei Starovoitov
2024-03-11 17:09 ` Quentin Monnet [this message]
2024-03-08 1:08 ` [PATCH v3 bpf-next 11/14] bpf: Add helper macro bpf_addr_space_cast() Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 12/14] selftests/bpf: Add unit tests for bpf_arena_alloc/free_pages Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 13/14] selftests/bpf: Add bpf_arena_list test Alexei Starovoitov
2024-03-08 1:08 ` [PATCH v3 bpf-next 14/14] selftests/bpf: Add bpf_arena_htab test Alexei Starovoitov
2024-03-11 22:45 ` [PATCH v3 bpf-next 00/14] bpf: Introduce BPF arena Andrii Nakryiko
2024-03-11 23:02 ` Alexei Starovoitov
2024-03-11 22:50 ` patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aa2bdd2d-4c85-4b64-ba77-7da0df4f4660@isovalent.com \
--to=quentin@isovalent.com \
--cc=akpm@linux-foundation.org \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brho@google.com \
--cc=daniel@iogearbox.net \
--cc=hannes@cmpxchg.org \
--cc=hch@infradead.org \
--cc=kernel-team@fb.com \
--cc=linux-mm@kvack.org \
--cc=torvalds@linux-foundation.org \
--cc=urezki@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox