From: Yonghong Song <yonghong.song@linux.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Eduard Zingerman <eddyz87@gmail.com>,
kernel-team@fb.com
Subject: [PATCH bpf-next v4 02/12] bpf: Drop the recursion depth argument of btf_type_is_scalar_struct()
Date: Fri, 28 Aug 2026 23:15:24 -0700 [thread overview]
Message-ID: <20260829061524.1692957-1-yonghong.song@linux.dev> (raw)
In-Reply-To: <20260829061514.1690730-1-yonghong.song@linux.dev>
btf_type_is_scalar_struct() recurses into nested struct members and
carries the nesting depth in a @rec argument, so every caller has to
spell out the 0 that starts the walk.
Move the recursion into btf_struct_member_walk() and leave
btf_type_is_scalar_struct() as a thin wrapper over it. This is
groundwork for the later patches, which give the walk further state
that callers should not have to supply: the kinds of member it accepts,
and a record of the member that made it fail.
No functional change.
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
include/linux/bpf_verifier.h | 2 +-
kernel/bpf/btf.c | 2 +-
kernel/bpf/verifier.c | 24 +++++++++++++++---------
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 004b06785521..3eb61edc8c5e 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -1489,7 +1489,7 @@ struct bpf_iarray *bpf_insn_successors(struct bpf_verifier_env *env, u32 idx);
void bpf_fmt_stack_mask(char *buf, ssize_t buf_sz, u64 stack_mask);
bool bpf_subprog_is_global(const struct bpf_verifier_env *env, int subprog);
bool btf_type_is_scalar_struct(struct bpf_verifier_env *env, const struct btf *btf,
- const struct btf_type *t, int rec);
+ const struct btf_type *t);
int bpf_find_subprog(struct bpf_verifier_env *env, int off);
bool bpf_is_throw_kfunc(struct bpf_insn *insn);
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 91b8ce77f699..47d43eb983a5 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -7995,7 +7995,7 @@ static int btf_validate_return_type(struct bpf_verifier_env *env, struct btf *bt
*/
bool local_func = subprog && !is_global;
- if (local_func || btf_type_is_scalar_struct(env, btf, t, 0))
+ if (local_func || btf_type_is_scalar_struct(env, btf, t))
return 0;
}
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 5d8162e13c20..ed077a5422af 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -11647,9 +11647,8 @@ static bool is_kfunc_arg_implicit(const struct bpf_call_arg_meta *meta, u32 arg_
}
/* Returns true if struct is composed of scalars, 4 levels of nesting allowed */
-bool btf_type_is_scalar_struct(struct bpf_verifier_env *env,
- const struct btf *btf,
- const struct btf_type *t, int rec)
+static bool btf_struct_member_walk(struct bpf_verifier_env *env, const struct btf *btf,
+ const struct btf_type *t, int rec)
{
const struct btf_type *member_type;
const struct btf_member *member;
@@ -11667,7 +11666,7 @@ bool btf_type_is_scalar_struct(struct bpf_verifier_env *env,
verbose(env, "max struct nesting depth exceeded\n");
return false;
}
- if (!btf_type_is_scalar_struct(env, btf, member_type, rec + 1))
+ if (!btf_struct_member_walk(env, btf, member_type, rec + 1))
return false;
continue;
}
@@ -11686,6 +11685,13 @@ bool btf_type_is_scalar_struct(struct bpf_verifier_env *env,
return true;
}
+bool btf_type_is_scalar_struct(struct bpf_verifier_env *env,
+ const struct btf *btf,
+ const struct btf_type *t)
+{
+ return btf_struct_member_walk(env, btf, t, 0);
+}
+
enum kfunc_ptr_arg_type {
KF_ARG_CONST_MEM_SIZE,
KF_ARG_MEM_SIZE,
@@ -12066,7 +12072,7 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
(is_kfunc_arg_mem_size(meta->btf, &args[arg + 1]) ||
is_kfunc_arg_const_mem_size(meta->btf, &args[arg + 1]))) {
if (!btf_type_is_void(ref_t) && !btf_type_is_scalar(ref_t) &&
- !btf_type_is_scalar_struct(env, meta->btf, ref_t, 0)) {
+ !btf_type_is_scalar_struct(env, meta->btf, ref_t)) {
verbose(env, "%s pointer type %s %s must point to void, scalar, or struct with scalar\n",
reg_arg_name(env, argno), btf_type_str(ref_t), ref_tname);
return -EINVAL;
@@ -12082,7 +12088,7 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
* scalars. The access size is derived from the pointed-to BTF type.
*/
if (!btf_type_is_scalar(ref_t) &&
- !btf_type_is_scalar_struct(env, meta->btf, ref_t, 0)) {
+ !btf_type_is_scalar_struct(env, meta->btf, ref_t)) {
verbose(env, "%s pointer type %s %s must point to scalar, or struct with scalar\n",
reg_arg_name(env, argno), btf_type_str(ref_t), ref_tname);
return -EINVAL;
@@ -13138,7 +13144,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
break;
}
- if (!btf_type_is_scalar_struct(env, meta->btf, ref_t, 0)) {
+ if (!btf_type_is_scalar_struct(env, meta->btf, ref_t)) {
enum bpf_reg_type reg2btf_type = lookup_reg2btf_ids(ref_id);
const char *expected_type;
@@ -13680,7 +13686,7 @@ static int check_special_kfunc(struct bpf_verifier_env *env, struct bpf_call_arg
struct_meta = btf_find_struct_meta(ret_btf, ret_btf_id);
if (is_bpf_percpu_obj_new_kfunc(meta->func_id)) {
- if (!btf_type_is_scalar_struct(env, ret_btf, ret_t, 0)) {
+ if (!btf_type_is_scalar_struct(env, ret_btf, ret_t)) {
verbose(env, "bpf_percpu_obj_new type ID argument must be of a struct of scalars\n");
return -EINVAL;
}
@@ -14059,7 +14065,7 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
* otherwise a pointer field would be laundered into a scalar
* and escape provenance and reference tracking.
*/
- if (!btf_type_is_scalar_struct(env, desc_btf, t, 0)) {
+ if (!btf_type_is_scalar_struct(env, desc_btf, t)) {
verbose(env,
"kernel function %s returns %s %s that is not composed of scalars\n",
func_name, btf_type_str(t),
--
2.53.0-Meta
next prev parent reply other threads:[~2026-08-29 6:15 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-29 6:15 [PATCH bpf-next v4 00/12] bpf: Allow arena pointers in by-value returns Yonghong Song
2026-08-29 6:15 ` [PATCH bpf-next v4 01/12] bpf: Record each half of a paired return value in verifier diagnostics Yonghong Song
2026-08-29 6:15 ` Yonghong Song [this message]
2026-08-29 6:15 ` [PATCH bpf-next v4 03/12] bpf: Add btf_type_is_arena_ptr() Yonghong Song
2026-08-29 6:15 ` [PATCH bpf-next v4 04/12] bpf: Let the by-value struct walk take the kinds of member it accepts Yonghong Song
2026-08-29 6:15 ` [PATCH bpf-next v4 05/12] bpf: Let a by-value struct nest arrays and structs freely Yonghong Song
2026-08-29 7:11 ` bot+bpf-ci
2026-08-29 6:15 ` [PATCH bpf-next v4 06/12] bpf: Report which member makes a kfunc return type unsupported Yonghong Song
2026-08-29 7:11 ` bot+bpf-ci
2026-08-29 6:15 ` [PATCH bpf-next v4 07/12] bpf: Allow a global function to return arena pointers by value Yonghong Song
2026-08-29 6:15 ` [PATCH bpf-next v4 08/12] bpf: Allow arena pointers in a by-value kfunc return Yonghong Song
2026-08-29 6:16 ` [PATCH bpf-next v4 09/12] selftests/bpf: Check the member named for an unsupported kfunc return type Yonghong Song
2026-08-29 6:16 ` [PATCH bpf-next v4 10/12] selftests/bpf: Test global functions returning arena pointers by value Yonghong Song
2026-08-29 6:16 ` [PATCH bpf-next v4 11/12] selftests/bpf: Test kfuncs " Yonghong Song
2026-08-29 6:16 ` [PATCH bpf-next v4 12/12] docs/bpf: Document arena pointers in a by-value return Yonghong Song
2026-08-30 1:33 ` Kumar Kartikeya Dwivedi
2026-08-31 2:42 ` Yonghong Song
2026-08-30 1:20 ` [PATCH bpf-next v4 00/12] bpf: Allow arena pointers in by-value returns 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=20260829061524.1692957-1-yonghong.song@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@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 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.