* [PATCH bpf-next] bpf: clean up btf_scan_decl_tags()
@ 2026-06-03 20:18 Matt Bobrowski
2026-06-04 15:59 ` Emil Tsalapatis
2026-06-04 16:50 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 4+ messages in thread
From: Matt Bobrowski @ 2026-06-03 20:18 UTC (permalink / raw)
To: bpf
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Jiri Olsa, Emil Tsalapatis, Matt Bobrowski
Refactor the newly introduced btf_scan_decl_tags() to improve
readability and maintainability. The current implementation uses a
manual if-else chain and a magic number offset to strip the "arg:"
prefix from declaration tags.
Replace the if-else logic with a table-driven approach using a static
const array. This separates the tag data from the scanning logic, making
the helper more extensible for future tags. Additionally, replace the
magic number '4' with a sizeof-based calculation on the prefix string to
ensure the offset remains synchronized with the search key.
Finally, optimize the loop by moving the is_global check to the top of
the block. This allows the verifier to fail-fast on static subprograms
without performing unnecessary BTF string and type lookups.
Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
---
kernel/bpf/btf.c | 46 ++++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 68921d9172b5..55aa3ba1b1e0 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -7808,14 +7808,28 @@ static int btf_scan_decl_tags(struct bpf_verifier_env *env,
u32 arg_idx, bool is_global, u32 *tags)
{
int id = btf_named_start_id(btf, false) - 1;
+ const char tag_key[] = "arg:";
+ static const struct {
+ const char *tag_value;
+ enum btf_arg_tag arg_tag;
+ } tag_values[] = {
+ { "ctx", ARG_TAG_CTX },
+ { "trusted", ARG_TAG_TRUSTED },
+ { "untrusted", ARG_TAG_UNTRUSTED },
+ { "nonnull", ARG_TAG_NONNULL },
+ { "nullable", ARG_TAG_NULLABLE },
+ { "arena", ARG_TAG_ARENA },
+ };
/*
* The 'arg:<tag>' decl_tag takes precedence over the derivation
* of the register type from the BTF type itself.
*/
- while ((id = btf_find_next_decl_tag(btf, fn_t, arg_idx, "arg:", id)) > 0) {
- const struct btf_type *tag_t = btf_type_by_id(btf, id);
- const char *tag = __btf_name_by_offset(btf, tag_t->name_off) + 4;
+ while ((id = btf_find_next_decl_tag(btf, fn_t, arg_idx, tag_key, id)) > 0) {
+ const struct btf_type *tag_t;
+ const char *tag;
+ int i;
+ bool found;
/* disallow arg tags in static subprogs */
if (!is_global) {
@@ -7825,19 +7839,19 @@ static int btf_scan_decl_tags(struct bpf_verifier_env *env,
return -EOPNOTSUPP;
}
- if (strcmp(tag, "ctx") == 0) {
- *tags |= ARG_TAG_CTX;
- } else if (strcmp(tag, "trusted") == 0) {
- *tags |= ARG_TAG_TRUSTED;
- } else if (strcmp(tag, "untrusted") == 0) {
- *tags |= ARG_TAG_UNTRUSTED;
- } else if (strcmp(tag, "nonnull") == 0) {
- *tags |= ARG_TAG_NONNULL;
- } else if (strcmp(tag, "nullable") == 0) {
- *tags |= ARG_TAG_NULLABLE;
- } else if (strcmp(tag, "arena") == 0) {
- *tags |= ARG_TAG_ARENA;
- } else {
+ tag_t = btf_type_by_id(btf, id);
+ tag = __btf_name_by_offset(btf, tag_t->name_off) + (sizeof(tag_key) - 1);
+
+ found = false;
+ for (i = 0; i < ARRAY_SIZE(tag_values); ++i) {
+ if (!strcmp(tag, tag_values[i].tag_value)) {
+ *tags |= tag_values[i].arg_tag;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
bpf_log(&env->log, "arg#%d has unsupported set of tags\n", arg_idx);
return -EOPNOTSUPP;
}
--
2.54.0.1032.g2f8565e1d1-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH bpf-next] bpf: clean up btf_scan_decl_tags()
2026-06-03 20:18 [PATCH bpf-next] bpf: clean up btf_scan_decl_tags() Matt Bobrowski
@ 2026-06-04 15:59 ` Emil Tsalapatis
2026-06-04 21:13 ` Matt Bobrowski
2026-06-04 16:50 ` patchwork-bot+netdevbpf
1 sibling, 1 reply; 4+ messages in thread
From: Emil Tsalapatis @ 2026-06-04 15:59 UTC (permalink / raw)
To: Matt Bobrowski, bpf
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Jiri Olsa, Emil Tsalapatis
On Wed Jun 3, 2026 at 4:18 PM EDT, Matt Bobrowski wrote:
> Refactor the newly introduced btf_scan_decl_tags() to improve
> readability and maintainability. The current implementation uses a
> manual if-else chain and a magic number offset to strip the "arg:"
> prefix from declaration tags.
>
> Replace the if-else logic with a table-driven approach using a static
> const array. This separates the tag data from the scanning logic, making
> the helper more extensible for future tags. Additionally, replace the
> magic number '4' with a sizeof-based calculation on the prefix string to
> ensure the offset remains synchronized with the search key.
>
> Finally, optimize the loop by moving the is_global check to the top of
> the block. This allows the verifier to fail-fast on static subprograms
> without performing unnecessary BTF string and type lookups.
>
> Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
We can also modify the new btf_scan_type_tags() to conform to the same
pattern. It currently recognizes a single type tag, so if anything it
would be more code, but we don't want it to slowly end up looking like
the if-else chain we're replacing below.
> ---
> kernel/bpf/btf.c | 46 ++++++++++++++++++++++++++++++----------------
> 1 file changed, 30 insertions(+), 16 deletions(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 68921d9172b5..55aa3ba1b1e0 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -7808,14 +7808,28 @@ static int btf_scan_decl_tags(struct bpf_verifier_env *env,
> u32 arg_idx, bool is_global, u32 *tags)
> {
> int id = btf_named_start_id(btf, false) - 1;
> + const char tag_key[] = "arg:";
> + static const struct {
> + const char *tag_value;
> + enum btf_arg_tag arg_tag;
> + } tag_values[] = {
> + { "ctx", ARG_TAG_CTX },
> + { "trusted", ARG_TAG_TRUSTED },
> + { "untrusted", ARG_TAG_UNTRUSTED },
> + { "nonnull", ARG_TAG_NONNULL },
> + { "nullable", ARG_TAG_NULLABLE },
> + { "arena", ARG_TAG_ARENA },
> + };
>
> /*
> * The 'arg:<tag>' decl_tag takes precedence over the derivation
> * of the register type from the BTF type itself.
> */
> - while ((id = btf_find_next_decl_tag(btf, fn_t, arg_idx, "arg:", id)) > 0) {
> - const struct btf_type *tag_t = btf_type_by_id(btf, id);
> - const char *tag = __btf_name_by_offset(btf, tag_t->name_off) + 4;
> + while ((id = btf_find_next_decl_tag(btf, fn_t, arg_idx, tag_key, id)) > 0) {
> + const struct btf_type *tag_t;
> + const char *tag;
> + int i;
> + bool found;
>
> /* disallow arg tags in static subprogs */
> if (!is_global) {
> @@ -7825,19 +7839,19 @@ static int btf_scan_decl_tags(struct bpf_verifier_env *env,
> return -EOPNOTSUPP;
> }
>
> - if (strcmp(tag, "ctx") == 0) {
> - *tags |= ARG_TAG_CTX;
> - } else if (strcmp(tag, "trusted") == 0) {
> - *tags |= ARG_TAG_TRUSTED;
> - } else if (strcmp(tag, "untrusted") == 0) {
> - *tags |= ARG_TAG_UNTRUSTED;
> - } else if (strcmp(tag, "nonnull") == 0) {
> - *tags |= ARG_TAG_NONNULL;
> - } else if (strcmp(tag, "nullable") == 0) {
> - *tags |= ARG_TAG_NULLABLE;
> - } else if (strcmp(tag, "arena") == 0) {
> - *tags |= ARG_TAG_ARENA;
> - } else {
> + tag_t = btf_type_by_id(btf, id);
> + tag = __btf_name_by_offset(btf, tag_t->name_off) + (sizeof(tag_key) - 1);
> +
> + found = false;
> + for (i = 0; i < ARRAY_SIZE(tag_values); ++i) {
> + if (!strcmp(tag, tag_values[i].tag_value)) {
> + *tags |= tag_values[i].arg_tag;
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found) {
> bpf_log(&env->log, "arg#%d has unsupported set of tags\n", arg_idx);
> return -EOPNOTSUPP;
> }
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH bpf-next] bpf: clean up btf_scan_decl_tags()
2026-06-03 20:18 [PATCH bpf-next] bpf: clean up btf_scan_decl_tags() Matt Bobrowski
2026-06-04 15:59 ` Emil Tsalapatis
@ 2026-06-04 16:50 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-06-04 16:50 UTC (permalink / raw)
To: Matt Bobrowski
Cc: bpf, ast, daniel, andrii, martin.lau, eddyz87, song,
yonghong.song, jolsa, emil
Hello:
This patch was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Wed, 3 Jun 2026 20:18:22 +0000 you wrote:
> Refactor the newly introduced btf_scan_decl_tags() to improve
> readability and maintainability. The current implementation uses a
> manual if-else chain and a magic number offset to strip the "arg:"
> prefix from declaration tags.
>
> Replace the if-else logic with a table-driven approach using a static
> const array. This separates the tag data from the scanning logic, making
> the helper more extensible for future tags. Additionally, replace the
> magic number '4' with a sizeof-based calculation on the prefix string to
> ensure the offset remains synchronized with the search key.
>
> [...]
Here is the summary with links:
- [bpf-next] bpf: clean up btf_scan_decl_tags()
https://git.kernel.org/bpf/bpf-next/c/fbd6dc50d9ae
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH bpf-next] bpf: clean up btf_scan_decl_tags()
2026-06-04 15:59 ` Emil Tsalapatis
@ 2026-06-04 21:13 ` Matt Bobrowski
0 siblings, 0 replies; 4+ messages in thread
From: Matt Bobrowski @ 2026-06-04 21:13 UTC (permalink / raw)
To: Emil Tsalapatis
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
Jiri Olsa
On Thu, Jun 04, 2026 at 11:59:26AM -0400, Emil Tsalapatis wrote:
> On Wed Jun 3, 2026 at 4:18 PM EDT, Matt Bobrowski wrote:
> > Refactor the newly introduced btf_scan_decl_tags() to improve
> > readability and maintainability. The current implementation uses a
> > manual if-else chain and a magic number offset to strip the "arg:"
> > prefix from declaration tags.
> >
> > Replace the if-else logic with a table-driven approach using a static
> > const array. This separates the tag data from the scanning logic, making
> > the helper more extensible for future tags. Additionally, replace the
> > magic number '4' with a sizeof-based calculation on the prefix string to
> > ensure the offset remains synchronized with the search key.
> >
> > Finally, optimize the loop by moving the is_global check to the top of
> > the block. This allows the verifier to fail-fast on static subprograms
> > without performing unnecessary BTF string and type lookups.
> >
> > Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
>
> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
>
> We can also modify the new btf_scan_type_tags() to conform to the same
> pattern. It currently recognizes a single type tag, so if anything it
> would be more code, but we don't want it to slowly end up looking like
> the if-else chain we're replacing below.
OK, I'll also take a look at btf_scan_type_tags() and if so adapt it
and send a patch through.
> > ---
> > kernel/bpf/btf.c | 46 ++++++++++++++++++++++++++++++----------------
> > 1 file changed, 30 insertions(+), 16 deletions(-)
> >
> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> > index 68921d9172b5..55aa3ba1b1e0 100644
> > --- a/kernel/bpf/btf.c
> > +++ b/kernel/bpf/btf.c
> > @@ -7808,14 +7808,28 @@ static int btf_scan_decl_tags(struct bpf_verifier_env *env,
> > u32 arg_idx, bool is_global, u32 *tags)
> > {
> > int id = btf_named_start_id(btf, false) - 1;
> > + const char tag_key[] = "arg:";
> > + static const struct {
> > + const char *tag_value;
> > + enum btf_arg_tag arg_tag;
> > + } tag_values[] = {
> > + { "ctx", ARG_TAG_CTX },
> > + { "trusted", ARG_TAG_TRUSTED },
> > + { "untrusted", ARG_TAG_UNTRUSTED },
> > + { "nonnull", ARG_TAG_NONNULL },
> > + { "nullable", ARG_TAG_NULLABLE },
> > + { "arena", ARG_TAG_ARENA },
> > + };
> >
> > /*
> > * The 'arg:<tag>' decl_tag takes precedence over the derivation
> > * of the register type from the BTF type itself.
> > */
> > - while ((id = btf_find_next_decl_tag(btf, fn_t, arg_idx, "arg:", id)) > 0) {
> > - const struct btf_type *tag_t = btf_type_by_id(btf, id);
> > - const char *tag = __btf_name_by_offset(btf, tag_t->name_off) + 4;
> > + while ((id = btf_find_next_decl_tag(btf, fn_t, arg_idx, tag_key, id)) > 0) {
> > + const struct btf_type *tag_t;
> > + const char *tag;
> > + int i;
> > + bool found;
> >
> > /* disallow arg tags in static subprogs */
> > if (!is_global) {
> > @@ -7825,19 +7839,19 @@ static int btf_scan_decl_tags(struct bpf_verifier_env *env,
> > return -EOPNOTSUPP;
> > }
> >
> > - if (strcmp(tag, "ctx") == 0) {
> > - *tags |= ARG_TAG_CTX;
> > - } else if (strcmp(tag, "trusted") == 0) {
> > - *tags |= ARG_TAG_TRUSTED;
> > - } else if (strcmp(tag, "untrusted") == 0) {
> > - *tags |= ARG_TAG_UNTRUSTED;
> > - } else if (strcmp(tag, "nonnull") == 0) {
> > - *tags |= ARG_TAG_NONNULL;
> > - } else if (strcmp(tag, "nullable") == 0) {
> > - *tags |= ARG_TAG_NULLABLE;
> > - } else if (strcmp(tag, "arena") == 0) {
> > - *tags |= ARG_TAG_ARENA;
> > - } else {
> > + tag_t = btf_type_by_id(btf, id);
> > + tag = __btf_name_by_offset(btf, tag_t->name_off) + (sizeof(tag_key) - 1);
> > +
> > + found = false;
> > + for (i = 0; i < ARRAY_SIZE(tag_values); ++i) {
> > + if (!strcmp(tag, tag_values[i].tag_value)) {
> > + *tags |= tag_values[i].arg_tag;
> > + found = true;
> > + break;
> > + }
> > + }
> > +
> > + if (!found) {
> > bpf_log(&env->log, "arg#%d has unsupported set of tags\n", arg_idx);
> > return -EOPNOTSUPP;
> > }
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-04 21:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03 20:18 [PATCH bpf-next] bpf: clean up btf_scan_decl_tags() Matt Bobrowski
2026-06-04 15:59 ` Emil Tsalapatis
2026-06-04 21:13 ` Matt Bobrowski
2026-06-04 16:50 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox