BPF List
 help / color / mirror / Atom feed
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>


  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