BPF List
 help / color / mirror / Atom feed
From: Alan Maguire <alan.maguire@oracle.com>
To: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net,
	kernel-team@fb.com, Song Liu <songliubraving@fb.com>
Subject: Re: [PATCH v2 bpf-next 1/2] libbpf: load global data maps lazily on legacy kernels
Date: Thu, 25 Nov 2021 22:21:12 +0000 (GMT)	[thread overview]
Message-ID: <alpine.LRH.2.23.451.2111252218190.318@localhost> (raw)
In-Reply-To: <20211123200105.387855-1-andrii@kernel.org>

On Tue, 23 Nov 2021, Andrii Nakryiko wrote:

> Load global data maps lazily, if kernel is too old to support global
> data. Make sure that programs are still correct by detecting if any of
> the to-be-loaded programs have relocation against any of such maps.
> 
> This allows to solve the issue ([0]) with bpf_printk() and Clang
> generating unnecessary and unreferenced .rodata.strX.Y sections, but it
> also goes further along the CO-RE lines, allowing to have a BPF object
> in which some code can work on very old kernels and relies only on BPF
> maps explicitly, while other BPF programs might enjoy global variable
> support. If such programs are correctly set to not load at runtime on
> old kernels, bpf_object will load and function correctly now.
> 
>   [0] https://lore.kernel.org/bpf/CAK-59YFPU3qO+_pXWOH+c1LSA=8WA1yabJZfREjOEXNHAqgXNg@mail.gmail.com/
> 
> Fixes: aed659170a31 ("libbpf: Support multiple .rodata.* and .data.* BPF maps")
> Acked-by: Song Liu <songliubraving@fb.com>
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

Thanks for fixing this! I ran into it today on a 4.14 kernel and verified 
that with the patch applied to latest libbpf, BPF objects with legacy maps 
loaded and ran where previously loading failed.

Tested-by: Alan Maguire <alan.maguire@oracle.com>
> ---
>  tools/lib/bpf/libbpf.c | 34 ++++++++++++++++++++++++++++++----
>  1 file changed, 30 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index af405c38aadc..27695bf31250 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -5006,6 +5006,24 @@ bpf_object__create_maps(struct bpf_object *obj)
>  	for (i = 0; i < obj->nr_maps; i++) {
>  		map = &obj->maps[i];
>  
> +		/* To support old kernels, we skip creating global data maps
> +		 * (.rodata, .data, .kconfig, etc); later on, during program
> +		 * loading, if we detect that at least one of the to-be-loaded
> +		 * programs is referencing any global data map, we'll error
> +		 * out with program name and relocation index logged.
> +		 * This approach allows to accommodate Clang emitting
> +		 * unnecessary .rodata.str1.1 sections for string literals,
> +		 * but also it allows to have CO-RE applications that use
> +		 * global variables in some of BPF programs, but not others.
> +		 * If those global variable-using programs are not loaded at
> +		 * runtime due to bpf_program__set_autoload(prog, false),
> +		 * bpf_object loading will succeed just fine even on old
> +		 * kernels.
> +		 */
> +		if (bpf_map__is_internal(map) &&
> +		    !kernel_supports(obj, FEAT_GLOBAL_DATA))
> +			continue;
> +
>  		retried = false;
>  retry:
>  		if (map->pin_path) {
> @@ -5605,6 +5623,14 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
>  				insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
>  				insn[0].imm = relo->map_idx;
>  			} else {
> +				const struct bpf_map *map = &obj->maps[relo->map_idx];
> +
> +				if (bpf_map__is_internal(map) &&
> +				    !kernel_supports(obj, FEAT_GLOBAL_DATA)) {
> +					pr_warn("prog '%s': relo #%d: kernel doesn't support global data\n",
> +						prog->name, i);
> +					return -ENOTSUP;
> +				}
>  				insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
>  				insn[0].imm = obj->maps[relo->map_idx].fd;
>  			}
> @@ -6139,6 +6165,8 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
>  		 */
>  		if (prog_is_subprog(obj, prog))
>  			continue;
> +		if (!prog->load)
> +			continue;
>  
>  		err = bpf_object__relocate_calls(obj, prog);
>  		if (err) {
> @@ -6152,6 +6180,8 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
>  		prog = &obj->programs[i];
>  		if (prog_is_subprog(obj, prog))
>  			continue;
> +		if (!prog->load)
> +			continue;
>  		err = bpf_object__relocate_data(obj, prog);
>  		if (err) {
>  			pr_warn("prog '%s': failed to relocate data references: %d\n",
> @@ -6939,10 +6969,6 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj)
>  	bpf_object__for_each_map(m, obj) {
>  		if (!bpf_map__is_internal(m))
>  			continue;
> -		if (!kernel_supports(obj, FEAT_GLOBAL_DATA)) {
> -			pr_warn("kernel doesn't support global data\n");
> -			return -ENOTSUP;
> -		}
>  		if (!kernel_supports(obj, FEAT_ARRAY_MMAP))
>  			m->def.map_flags ^= BPF_F_MMAPABLE;
>  	}
> -- 
> 2.30.2
> 
> 

      parent reply	other threads:[~2021-11-25 22:23 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-23 20:01 [PATCH v2 bpf-next 1/2] libbpf: load global data maps lazily on legacy kernels Andrii Nakryiko
2021-11-23 20:01 ` [PATCH v2 bpf-next 2/2] selftests/bpf: mix legacy (maps) and modern (vars) BPF in one test Andrii Nakryiko
2021-11-25 22:10 ` [PATCH v2 bpf-next 1/2] libbpf: load global data maps lazily on legacy kernels patchwork-bot+netdevbpf
2021-11-25 22:21 ` Alan Maguire [this message]

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=alpine.LRH.2.23.451.2111252218190.318@localhost \
    --to=alan.maguire@oracle.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kernel-team@fb.com \
    --cc=songliubraving@fb.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