From: "Emil Tsalapatis" <emil@etsalapatis.com>
To: "Emil Tsalapatis" <emil@etsalapatis.com>, <bpf@vger.kernel.org>
Cc: <andrii@kernel.org>, <ast@kernel.org>, <daniel@iogearbox.net>,
<eddyz87@gmail.com>, <martin.lau@kernel.org>, <memxor@gmail.com>,
<song@kernel.org>, <yonghong.song@linux.dev>
Subject: Re: [PATCH bpf-next v2] libbpf: Add gating for arena globals relocation feature
Date: Mon, 09 Feb 2026 19:26:27 -0500 [thread overview]
Message-ID: <DGAUSYFN8OW4.2D08XFDK2CPG9@etsalapatis.com> (raw)
In-Reply-To: <DGAUH7XDYUV0.1J1I31HIRDODC@etsalapatis.com>
On Mon Feb 9, 2026 at 7:11 PM EST, Emil Tsalapatis wrote:
> On Mon Feb 9, 2026 at 6:48 PM EST, Emil Tsalapatis wrote:
>> Add feature gating for the arena globals relocation introduced in
>> commit c1f61171d44b. The commit depends on a previous commit in the
>> same patchset that is absent from older kernels (12a1fe6e12db,
>> "bpf/verifier: Do not limit maximum direct offset into arena map").
>> Without this commit, arena globals relocation with arenas >= 512MiB
>> fails to load and breaks libbpf's backwards compatibility.
>>
>> Introduce a libbpf feature to check whether the running kernel includes
>> patch 12a1fe6e12db, and only relocate arena globals if it does.
>>
>> CHANGELOG
>> ---------
>>
>> v1 -> v2 (https://lore.kernel.org/bpf/20260209210240.2051209-1-emil@etsalapatis.com/)
>>
>> - Reworked test to use simpler array-based program (Andrii)
>>
>> Fixes: c1f61171d44b ("libbpf: Move arena globals to the end of the arena")
>> Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
>> ---
>
> This patch does not properly parse the verifier log for kernels without
> 12a1fe6e12db. Will fix and respin.
>
Actually the patch works as intended: I thought the arena tests should
have been successful even after reverting 12a1fe6e12db, but that is not
the case. I still missed one of Andrii's points on v2 so I'll respin
anyway.
>> tools/lib/bpf/features.c | 92 +++++++++++++++++++++++++++++++++
>> tools/lib/bpf/libbpf.c | 7 ++-
>> tools/lib/bpf/libbpf_internal.h | 2 +
>> 3 files changed, 99 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c
>> index b842b83e2480..b1a088dd83ac 100644
>> --- a/tools/lib/bpf/features.c
>> +++ b/tools/lib/bpf/features.c
>> @@ -506,6 +506,95 @@ static int probe_kern_arg_ctx_tag(int token_fd)
>> return probe_fd(prog_fd);
>> }
>>
>> +static int probe_kern_arena_global_reloc(int token_fd)
>> +{
>> + const size_t bufsz = 1024;
>> + int btf_fd, prog_fd, map;
>> + char log_buf[bufsz];
>> + int ret;
>> + static const char strs[] = "\0f\0";
>> + const __u32 types[] = {
>> + /* [1] FUNC_PROTO `void(void)` */
>> + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),
>> + /* [2] FUNC 'f' -> FUNC_PROTO (main prog) */
>> + BTF_TYPE_ENC(1 /* "f" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 1),
>> + };
>> + LIBBPF_OPTS(bpf_map_create_opts, map_opts,
>> + .token_fd = token_fd,
>> + .map_flags = token_fd ? BPF_F_TOKEN_FD : 0,
>> + );
>> + LIBBPF_OPTS(bpf_prog_load_opts, prog_opts,
>> + .token_fd = token_fd,
>> + .prog_flags = BPF_F_SLEEPABLE | (token_fd ? BPF_F_TOKEN_FD : 0),
>> + .log_buf = log_buf,
>> + .log_size = bufsz,
>> + );
>> + struct bpf_insn insns[] = {
>> + BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1UL << 30),
>> + BPF_EXIT_INSN(),
>> + };
>> + const struct bpf_func_info_min func_infos[] = {
>> + { 0, 2 }, /* main prog -> FUNC 'f' */
>> + };
>> + int insn_cnt = ARRAY_SIZE(insns);
>> +
>> + btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), token_fd);
>> + if (btf_fd < 0)
>> + return 0; /* BTF not supported at all */
>> +
>> + map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "arr", sizeof(int), 1, 1, &map_opts);
>> + if (map < 0) {
>> + ret = -errno;
>> + pr_warn("Error in %s(): %s. Couldn't create simple array map.\n",
>> + __func__, errstr(ret));
>> + close(btf_fd);
>> + return ret;
>> + }
>> + insns[0].imm = map;
>> +
>> + prog_opts.prog_btf_fd = btf_fd;
>> + prog_opts.func_info = &func_infos;
>> + prog_opts.func_info_cnt = ARRAY_SIZE(func_infos);
>> + prog_opts.func_info_rec_size = sizeof(func_infos[0]);
>> +
>> + prog_fd = bpf_prog_load(BPF_PROG_TYPE_SYSCALL, "global_reloc", "GPL", insns, insn_cnt, &prog_opts);
>> +
>> + ret = -errno;
>> + close(map);
>> + close(btf_fd);
>> +
>> + if (prog_fd >= 0) {
>> + pr_warn("Error in %s(): Program loading unexpectedly succeeded.\n",
>> + __func__);
>> + close(prog_fd);
>> + return -EINVAL;
>> + }
>> +
>> + /* Be conservative and NULL terminate the buffer to ensure strstr terminates. */
>> + log_buf[bufsz - 1] = '\0';
>> +
>> + /*
>> + * Feature is allowed if we're not failing with the error message "direct value
>> + * offset of %u is not allowed that was removed in 12a1fe6e12db
>> + * ("bpf/verifier: Do not limit maximum direct offset into arena map").
>> + * Instead, we should be failing with the message "invalid access to map value
>> + * pointer". Ensure we match with one of the two and we're not failing with a
>> + * different, unexpected message.
>> + */
>> + if (strstr(log_buf, "direct value offset of"))
>> + return 0;
>> +
>> + if (strstr(log_buf, "invalid access to map value pointer") == NULL) {
>> + pr_warn("Error in %s(): Program unexpectedly failed with message: %s.\n",
>> + __func__, log_buf);
>> + return ret;
>> + }
>> +
>> + /* Feature is on. */
>> +
>> + return 1;
>> +}
>> +
>> typedef int (*feature_probe_fn)(int /* token_fd */);
>>
>> static struct kern_feature_cache feature_cache;
>> @@ -581,6 +670,9 @@ static struct kern_feature_desc {
>> [FEAT_BTF_QMARK_DATASEC] = {
>> "BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec,
>> },
>> + [FEAT_ARENA_GLOBAL_RELOC] = {
>> + "Relocatable arena globals support", probe_kern_arena_global_reloc,
>> + },
>> };
>>
>> bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)
>> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
>> index 0c8bf0b5cce4..0aeb740a5f47 100644
>> --- a/tools/lib/bpf/libbpf.c
>> +++ b/tools/lib/bpf/libbpf.c
>> @@ -3009,8 +3009,11 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map,
>> memcpy(obj->arena_data, data, data_sz);
>> obj->arena_data_sz = data_sz;
>>
>> - /* place globals at the end of the arena */
>> - obj->arena_data_off = mmap_sz - data_alloc_sz;
>> + /* place globals at the end of the arena (if supported) */
>> + if (kernel_supports(obj, FEAT_ARENA_GLOBAL_RELOC))
>> + obj->arena_data_off = mmap_sz - data_alloc_sz;
>> + else
>> + obj->arena_data_off = 0;
>>
>> /* make bpf_map__init_value() work for ARENA maps */
>> map->mmaped = obj->arena_data;
>> diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
>> index fc59b21b51b5..e0223a6e4c95 100644
>> --- a/tools/lib/bpf/libbpf_internal.h
>> +++ b/tools/lib/bpf/libbpf_internal.h
>> @@ -392,6 +392,8 @@ enum kern_feature_id {
>> FEAT_ARG_CTX_TAG,
>> /* Kernel supports '?' at the front of datasec names */
>> FEAT_BTF_QMARK_DATASEC,
>> + /* Kernel supports relocating arena globals to end of the arena */
>> + FEAT_ARENA_GLOBAL_RELOC,
>> __FEAT_CNT,
>> };
>>
next prev parent reply other threads:[~2026-02-10 0:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-09 23:48 [PATCH bpf-next v2] libbpf: Add gating for arena globals relocation feature Emil Tsalapatis
2026-02-10 0:11 ` Emil Tsalapatis
2026-02-10 0:26 ` Emil Tsalapatis [this message]
2026-02-10 0:16 ` bot+bpf-ci
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=DGAUSYFN8OW4.2D08XFDK2CPG9@etsalapatis.com \
--to=emil@etsalapatis.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=martin.lau@kernel.org \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.