* [PATCH bpf-next] bpf: simplify code by exporting a btf helper
@ 2025-06-24 19:36 Anton Protopopov
2025-06-24 21:10 ` Eduard Zingerman
0 siblings, 1 reply; 3+ messages in thread
From: Anton Protopopov @ 2025-06-24 19:36 UTC (permalink / raw)
To: bpf; +Cc: Anton Protopopov, Eduard Zingerman
There are places in code which can be simplified by using the
btf_type_is_regular_int() helper (slightly patched to add an
additional, optional, argument to check the exact size). So
patch the helper, export it, and simplify code in a few files.
(Suggested by Eduard in a bit different form in [1].)
[1] https://lore.kernel.org/bpf/7edb47e73baa46705119a23c6bf4af26517a640f.camel@gmail.com/
Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
---
include/linux/btf.h | 1 +
kernel/bpf/arraymap.c | 11 +++------
kernel/bpf/bpf_local_storage.c | 8 +------
kernel/bpf/btf.c | 43 +++++++++++++++++-----------------
kernel/bpf/local_storage.c | 9 +------
5 files changed, 27 insertions(+), 45 deletions(-)
diff --git a/include/linux/btf.h b/include/linux/btf.h
index b2983706292f..dbd52be2dbc4 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -221,6 +221,7 @@ bool btf_is_vmlinux(const struct btf *btf);
struct module *btf_try_get_module(const struct btf *btf);
u32 btf_nr_types(const struct btf *btf);
struct btf *btf_base_btf(const struct btf *btf);
+bool btf_type_is_regular_int(const struct btf_type *t, size_t expected_size);
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
const struct btf_member *m,
u32 expected_offset, u32 expected_size);
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index eb28c0f219ee..f7f84800c1dc 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -530,8 +530,6 @@ static int array_map_check_btf(const struct bpf_map *map,
const struct btf_type *key_type,
const struct btf_type *value_type)
{
- u32 int_data;
-
/* One exception for keyless BTF: .bss/.data/.rodata map */
if (btf_type_is_void(key_type)) {
if (map->map_type != BPF_MAP_TYPE_ARRAY ||
@@ -544,14 +542,11 @@ static int array_map_check_btf(const struct bpf_map *map,
return 0;
}
- if (BTF_INFO_KIND(key_type->info) != BTF_KIND_INT)
- return -EINVAL;
-
- int_data = *(u32 *)(key_type + 1);
- /* bpf array can only take a u32 key. This check makes sure
+ /*
+ * Bpf array can only take a u32 key. This check makes sure
* that the btf matches the attr used during map_create.
*/
- if (BTF_INT_BITS(int_data) != 32 || BTF_INT_OFFSET(int_data))
+ if (!btf_type_is_regular_int(key_type, sizeof(u32)))
return -EINVAL;
return 0;
diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
index fa56c30833ff..1ea8fb93d55e 100644
--- a/kernel/bpf/bpf_local_storage.c
+++ b/kernel/bpf/bpf_local_storage.c
@@ -722,13 +722,7 @@ int bpf_local_storage_map_check_btf(const struct bpf_map *map,
const struct btf_type *key_type,
const struct btf_type *value_type)
{
- u32 int_data;
-
- if (BTF_INFO_KIND(key_type->info) != BTF_KIND_INT)
- return -EINVAL;
-
- int_data = *(u32 *)(key_type + 1);
- if (BTF_INT_BITS(int_data) != 32 || BTF_INT_OFFSET(int_data))
+ if (!btf_type_is_regular_int(key_type, sizeof(u32)))
return -EINVAL;
return 0;
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 682acb1ed234..ea21b74d5027 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -857,27 +857,27 @@ const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id)
}
EXPORT_SYMBOL_GPL(btf_type_by_id);
-/*
- * Regular int is not a bit field and it must be either
- * u8/u16/u32/u64 or __int128.
- */
-static bool btf_type_int_is_regular(const struct btf_type *t)
+static bool btf_type_int_is_regular(const struct btf_type *t, size_t expected_size)
{
- u8 nr_bits, nr_bytes;
- u32 int_data;
+ u32 int_data = btf_type_int(t);
+ u8 nr_bits = BTF_INT_BITS(int_data);
+ u8 nr_bytes = BITS_ROUNDUP_BYTES(nr_bits);
- int_data = btf_type_int(t);
- nr_bits = BTF_INT_BITS(int_data);
- nr_bytes = BITS_ROUNDUP_BYTES(nr_bits);
- if (BITS_PER_BYTE_MASKED(nr_bits) ||
- BTF_INT_OFFSET(int_data) ||
- (nr_bytes != sizeof(u8) && nr_bytes != sizeof(u16) &&
- nr_bytes != sizeof(u32) && nr_bytes != sizeof(u64) &&
- nr_bytes != (2 * sizeof(u64)))) {
- return false;
- }
+ return BITS_PER_BYTE_MASKED(nr_bits) == 0 &&
+ BTF_INT_OFFSET(int_data) == 0 &&
+ (nr_bytes <= 16 && is_power_of_2(nr_bytes)) &&
+ (expected_size == 0 || nr_bytes == expected_size);
+}
- return true;
+/*
+ * Check that the type @t is a regular int. This means that @t is not
+ * a bit field and it has the same size as either of u8/u16/u32/u64
+ * or __int128. If @expected_size is not zero, then size of @t should
+ * be the same.
+ */
+bool btf_type_is_regular_int(const struct btf_type *t, size_t expected_size)
+{
+ return btf_type_is_int(t) && btf_type_int_is_regular(t, expected_size);
}
/*
@@ -2180,7 +2180,7 @@ static int btf_int_check_kflag_member(struct btf_verifier_env *env,
u32 nr_copy_bits;
/* a regular int type is required for the kflag int member */
- if (!btf_type_int_is_regular(member_type)) {
+ if (!btf_type_int_is_regular(member_type, 0)) {
btf_verifier_log_member(env, struct_type, member,
"Invalid member base type");
return -EINVAL;
@@ -2969,8 +2969,7 @@ static int btf_array_resolve(struct btf_verifier_env *env,
return env_stack_push(env, index_type, index_type_id);
index_type = btf_type_id_size(btf, &index_type_id, NULL);
- if (!index_type || !btf_type_is_int(index_type) ||
- !btf_type_int_is_regular(index_type)) {
+ if (!index_type || !btf_type_is_regular_int(index_type, 0)) {
btf_verifier_log_type(env, v->t, "Invalid index");
return -EINVAL;
}
@@ -2995,7 +2994,7 @@ static int btf_array_resolve(struct btf_verifier_env *env,
return -EINVAL;
}
- if (btf_type_is_int(elem_type) && !btf_type_int_is_regular(elem_type)) {
+ if (btf_type_is_int(elem_type) && !btf_type_int_is_regular(elem_type, 0)) {
btf_verifier_log_type(env, v->t, "Invalid array of int");
return -EINVAL;
}
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index 3969eb0382af..8645a39e8dd1 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -394,17 +394,10 @@ static int cgroup_storage_check_btf(const struct bpf_map *map,
if (!btf_member_is_reg_int(btf, key_type, m, offset, size))
return -EINVAL;
} else {
- u32 int_data;
-
/*
* Key is expected to be u64, which stores the cgroup_inode_id
*/
-
- if (BTF_INFO_KIND(key_type->info) != BTF_KIND_INT)
- return -EINVAL;
-
- int_data = *(u32 *)(key_type + 1);
- if (BTF_INT_BITS(int_data) != 64 || BTF_INT_OFFSET(int_data))
+ if (!btf_type_is_regular_int(key_type, sizeof(u64)))
return -EINVAL;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH bpf-next] bpf: simplify code by exporting a btf helper
2025-06-24 19:36 [PATCH bpf-next] bpf: simplify code by exporting a btf helper Anton Protopopov
@ 2025-06-24 21:10 ` Eduard Zingerman
2025-06-25 15:12 ` Anton Protopopov
0 siblings, 1 reply; 3+ messages in thread
From: Eduard Zingerman @ 2025-06-24 21:10 UTC (permalink / raw)
To: Anton Protopopov, bpf
On Tue, 2025-06-24 at 19:36 +0000, Anton Protopopov wrote:
> There are places in code which can be simplified by using the
> btf_type_is_regular_int() helper (slightly patched to add an
> additional, optional, argument to check the exact size). So
> patch the helper, export it, and simplify code in a few files.
> (Suggested by Eduard in a bit different form in [1].)
>
> [1] https://lore.kernel.org/bpf/7edb47e73baa46705119a23c6bf4af26517a640f.camel@gmail.com/
>
> Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
> ---
I think such cleanup makes sense.
Imo, the patch would be a bit simpler if:
- original interface of the btf_type_int_is_regular() is preserved,
thus avoiding most of the changes in the btf.c;
- helpers btf_is_i32 and btf_is_i64 are introduced for external usage.
E.g. like here:
https://github.com/kernel-patches/bpf/commit/d3c003f0a83cb66700f6a6e9b750d8e425b53cf5
(I use btf_is_u{32,64} there, but it should be i{32,64}).
Nit: the subject is a bit too generic.
[...]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH bpf-next] bpf: simplify code by exporting a btf helper
2025-06-24 21:10 ` Eduard Zingerman
@ 2025-06-25 15:12 ` Anton Protopopov
0 siblings, 0 replies; 3+ messages in thread
From: Anton Protopopov @ 2025-06-25 15:12 UTC (permalink / raw)
To: Eduard Zingerman; +Cc: bpf
On 25/06/24 02:10PM, Eduard Zingerman wrote:
> On Tue, 2025-06-24 at 19:36 +0000, Anton Protopopov wrote:
> > There are places in code which can be simplified by using the
> > btf_type_is_regular_int() helper (slightly patched to add an
> > additional, optional, argument to check the exact size). So
> > patch the helper, export it, and simplify code in a few files.
> > (Suggested by Eduard in a bit different form in [1].)
> >
> > [1] https://lore.kernel.org/bpf/7edb47e73baa46705119a23c6bf4af26517a640f.camel@gmail.com/
> >
> > Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
> > Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
> > ---
>
> I think such cleanup makes sense.
> Imo, the patch would be a bit simpler if:
> - original interface of the btf_type_int_is_regular() is preserved,
> thus avoiding most of the changes in the btf.c;
> - helpers btf_is_i32 and btf_is_i64 are introduced for external usage.
>
> E.g. like here:
> https://github.com/kernel-patches/bpf/commit/d3c003f0a83cb66700f6a6e9b750d8e425b53cf5
> (I use btf_is_u{32,64} there, but it should be i{32,64}).
Thanks. I also was choosing between this and what I've sent,
will send v2.
> Nit: the subject is a bit too generic.
Agree
> [...]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-06-25 15:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-24 19:36 [PATCH bpf-next] bpf: simplify code by exporting a btf helper Anton Protopopov
2025-06-24 21:10 ` Eduard Zingerman
2025-06-25 15:12 ` Anton Protopopov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).