All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] libbpf: support STRUCT_OPS in light skeletons
@ 2026-05-26 12:12 Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 1/3] libbpf: load vmlinux BTF in gen_loader mode for struct_ops Siddharth Nayyar
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Siddharth Nayyar @ 2026-05-26 12:12 UTC (permalink / raw)
  To: Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa
  Cc: bpf, linux-kernel, gprocida, maennich, Siddharth Nayyar

This series enables support for BPF `STRUCT_OPS` maps (such as
`sched_ext_ops` used by sched_ext) when using light skeletons (i.e.
`gen_loader` mode).

Previously, generating light skeletons for objects containing
`STRUCT_OPS` maps would fail or produce incomplete results because
`gen_loader` lacked support for several key features required by
`STRUCT_OPS` maps, specifically:

1. Loading `vmlinux` BTF to resolve kernel-side type information.
2. Correctly plumbing `btf_vmlinux_value_type_id` into map creation
   attributes.
3. Ensuring `btf_key_type_id` is zeroed out to satisfy kernel safety
   checks.
4. Plumbing the userspace BTF FD (`btf_fd`) when
   `btf_vmlinux_value_type_id` is present but `btf_value_type_id` is
   zero (which is always the case for `STRUCT_OPS` maps).

This series addresses these limitations by:

- Loading `vmlinux` BTF in `gen_loader` mode when the BPF object
  contains `struct_ops` maps.
- Explicitly zeroing out `btf_key_type_id` for `STRUCT_OPS` maps to
  satisfy kernel validations.
- Expanding the map creation attribute size in `gen_loader` to include
  `btf_vmlinux_value_type_id` and plumbing it.
- Fixing `btf_fd` copying logic in `gen_loader` to populate it if either
  `btf_value_type_id` or `btf_vmlinux_value_type_id` is set.

With these changes, it is now possible to generate and use light
skeletons for BPF programs utilizing `STRUCT_OPS`, such as custom
sched_ext schedulers.

Signed-off-by: Siddharth Nayyar <sidnayyar@google.com>
---
Changes in v2:
- Expand the series to 3 patches to fully support STRUCT_OPS in gen_loader.
- Add a patch to explicitly zero out btf_key_type_id for STRUCT_OPS maps.
- Add a patch to plumb btf_vmlinux_value_type_id and btf_fd in gen_loader.
- Link to v1: https://lore.kernel.org/r/20260524-libbpf-load-vmlinux-btf-in-gen_loader-mode-v1-1-6f57f191a7ad@google.com

---
Siddharth Nayyar (3):
      libbpf: load vmlinux BTF in gen_loader mode for struct_ops
      libbpf: zero out btf_key_type_id for STRUCT_OPS maps
      libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader

 tools/lib/bpf/gen_loader.c | 5 +++--
 tools/lib/bpf/libbpf.c     | 6 +++++-
 2 files changed, 8 insertions(+), 3 deletions(-)
---
base-commit: c6e99c10fd9855082568cbd71bb2cc5dc90eda53
change-id: 20260522-libbpf-load-vmlinux-btf-in-gen_loader-mode-4474834aa467

Best regards,
-- 
Siddharth Nayyar <sidnayyar@google.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] libbpf: load vmlinux BTF in gen_loader mode for struct_ops
  2026-05-26 12:12 [PATCH v2 0/3] libbpf: support STRUCT_OPS in light skeletons Siddharth Nayyar
@ 2026-05-26 12:12 ` Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 2/3] libbpf: zero out btf_key_type_id for STRUCT_OPS maps Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 3/3] libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader Siddharth Nayyar
  2 siblings, 0 replies; 5+ messages in thread
From: Siddharth Nayyar @ 2026-05-26 12:12 UTC (permalink / raw)
  To: Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa
  Cc: bpf, linux-kernel, gprocida, maennich, Siddharth Nayyar

During light skeleton generation (`bpftool gen skeleton -L`), libbpf
runs in gen_loader mode. Previously, `bpf_object__load_vmlinux_btf()`
completely bypassed loading the kernel vmlinux BTF (`obj->btf_vmlinux`)
if `gen_loader` was active.

However, BPF `struct_ops` maps (such as `sched_ext_ops` maps) require
resolving the kernel-side struct type IDs and member sizes at
compile/skeleton generation time. Without loading `btf_vmlinux`, libbpf
cannot query the kernel BTF types, causing light skeleton generation for
`struct_ops` to fail or omit crucial type information.

Fix this by modifying the check to load `btf_vmlinux` even in
`gen_loader` mode if the BPF object actually requires kernel vmlinux BTF
(e.g. contains `struct_ops` maps).

Signed-off-by: Siddharth Nayyar <sidnayyar@google.com>
---
 tools/lib/bpf/libbpf.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3a80a018fc7d..cb1b7ea884a7 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -3590,7 +3590,10 @@ static int bpf_object__load_vmlinux_btf(struct bpf_object *obj, bool force)
 	int err;
 
 	/* btf_vmlinux could be loaded earlier */
-	if (obj->btf_vmlinux || obj->gen_loader)
+	if (obj->btf_vmlinux)
+		return 0;
+
+	if (obj->gen_loader && !obj_needs_vmlinux_btf(obj))
 		return 0;
 
 	if (!force && !obj_needs_vmlinux_btf(obj))

-- 
2.54.0.746.g67dd491aae-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] libbpf: zero out btf_key_type_id for STRUCT_OPS maps
  2026-05-26 12:12 [PATCH v2 0/3] libbpf: support STRUCT_OPS in light skeletons Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 1/3] libbpf: load vmlinux BTF in gen_loader mode for struct_ops Siddharth Nayyar
@ 2026-05-26 12:12 ` Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 3/3] libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader Siddharth Nayyar
  2 siblings, 0 replies; 5+ messages in thread
From: Siddharth Nayyar @ 2026-05-26 12:12 UTC (permalink / raw)
  To: Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa
  Cc: bpf, linux-kernel, gprocida, maennich, Siddharth Nayyar

For BPF `STRUCT_OPS` maps (such as `sched_ext_ops` maps), the kernel BPF
subsystem enforces strict map-creation safety validations inside
`map_create()`.  That is, if `btf_vmlinux_value_type_id` is set, the
kernel forbids passing any userspace `btf_key_type_id` or
`btf_value_type_id` (they must both be `0`).

However, inside libbpf's map-creation options initialization
(`bpf_object__create_map()`), libbpf zeroed out
`create_attr.btf_value_type_id` but does not zero out
`create_attr.btf_key_type_id`.

Fix this by explicitly zeroing out `create_attr.btf_key_type_id`.

Signed-off-by: Siddharth Nayyar <sidnayyar@google.com>
---
 tools/lib/bpf/libbpf.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index cb1b7ea884a7..9969de42da41 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -5439,6 +5439,7 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b
 		map->btf_value_type_id = 0;
 		break;
 	case BPF_MAP_TYPE_STRUCT_OPS:
+		create_attr.btf_key_type_id = 0;
 		create_attr.btf_value_type_id = 0;
 		break;
 	default:

-- 
2.54.0.746.g67dd491aae-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader
  2026-05-26 12:12 [PATCH v2 0/3] libbpf: support STRUCT_OPS in light skeletons Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 1/3] libbpf: load vmlinux BTF in gen_loader mode for struct_ops Siddharth Nayyar
  2026-05-26 12:12 ` [PATCH v2 2/3] libbpf: zero out btf_key_type_id for STRUCT_OPS maps Siddharth Nayyar
@ 2026-05-26 12:12 ` Siddharth Nayyar
  2026-05-26 13:57   ` sashiko-bot
  2 siblings, 1 reply; 5+ messages in thread
From: Siddharth Nayyar @ 2026-05-26 12:12 UTC (permalink / raw)
  To: Andrii Nakryiko, Eduard Zingerman, Alexei Starovoitov,
	Daniel Borkmann, Martin KaFai Lau, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa
  Cc: bpf, linux-kernel, gprocida, maennich, Siddharth Nayyar

BPF `STRUCT_OPS` maps (such as `sched_ext_ops` maps) require resolving
and plumbing the kernel-side structure value type ID
(`btf_vmlinux_value_type_id`) into the BPF map creation system call
attributes. Additionally, when `btf_vmlinux_value_type_id` is supplied,
the kernel requires a valid userspace BTF file descriptor (`btf_fd`) to
be supplied to verify types.

Previously, the `gen_loader` map creation generator
(`bpf_gen__map_create()`) completely omitted plumbing
`btf_vmlinux_value_type_id` because `attr_size` was calculated only up
to `map_extra` (which resides before `btf_vmlinux_value_type_id` in
`union bpf_attr`).

Furthermore, `gen_loader.c` only copied the loaded `btf_fd` from the
stack to the attributes blob if `btf_value_type_id` was non-zero.
Because `STRUCT_OPS` maps explicitly zero out `btf_value_type_id`, the
loader program skipped copying `btf_fd`, leaving it as `0` (standard
input), which caused the kernel's `btf_get_by_fd(0)` check to fail.

Fix this by:

1. Expanding `attr_size` inside `bpf_gen__map_create()` to include
   `btf_vmlinux_value_type_id` and copying it from the options.
2. Modifying the `btf_fd` copying condition to populate `btf_fd` if
   either `btf_value_type_id` OR `btf_vmlinux_value_type_id` is set.

Signed-off-by: Siddharth Nayyar <sidnayyar@google.com>
---
 tools/lib/bpf/gen_loader.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
index cd5c2543f54d..27b0353d1082 100644
--- a/tools/lib/bpf/gen_loader.c
+++ b/tools/lib/bpf/gen_loader.c
@@ -507,7 +507,7 @@ void bpf_gen__map_create(struct bpf_gen *gen,
 			 __u32 key_size, __u32 value_size, __u32 max_entries,
 			 struct bpf_map_create_opts *map_attr, int map_idx)
 {
-	int attr_size = offsetofend(union bpf_attr, map_extra);
+	int attr_size = offsetofend(union bpf_attr, btf_vmlinux_value_type_id);
 	bool close_inner_map_fd = false;
 	int map_create_attr, idx;
 	union bpf_attr attr;
@@ -525,13 +525,14 @@ void bpf_gen__map_create(struct bpf_gen *gen,
 	attr.max_entries = tgt_endian(max_entries);
 	attr.btf_key_type_id = tgt_endian(map_attr->btf_key_type_id);
 	attr.btf_value_type_id = tgt_endian(map_attr->btf_value_type_id);
+	attr.btf_vmlinux_value_type_id = tgt_endian(map_attr->btf_vmlinux_value_type_id);
 
 	map_create_attr = add_data(gen, &attr, attr_size);
 	pr_debug("gen: map_create: %s idx %d type %d value_type_id %d, attr: off %d size %d\n",
 		 map_name, map_idx, map_type, map_attr->btf_value_type_id,
 		 map_create_attr, attr_size);
 
-	if (map_attr->btf_value_type_id)
+	if (map_attr->btf_value_type_id || map_attr->btf_vmlinux_value_type_id)
 		/* populate union bpf_attr with btf_fd saved in the stack earlier */
 		move_stack2blob(gen, attr_field(map_create_attr, btf_fd), 4,
 				stack_off(btf_fd));

-- 
2.54.0.746.g67dd491aae-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 3/3] libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader
  2026-05-26 12:12 ` [PATCH v2 3/3] libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader Siddharth Nayyar
@ 2026-05-26 13:57   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-05-26 13:57 UTC (permalink / raw)
  To: Siddharth Nayyar; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The patch incorrectly reduces `attr_size` when constructing the BPF map creation attributes, silently truncating and discarding the `map_extra` field.
--

commit 72a5ab975182d8bdeec79a02a460190b45ceeb56
Author: Siddharth Nayyar <sidnayyar@google.com>

libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader

This commit updates the gen_loader map creation logic to include
btf_vmlinux_value_type_id and conditionally copy the loaded btf_fd into
the BPF attributes blob. It also alters the attr_size calculation based
on an assumption about the layout of union bpf_attr.

>     Previously, the `gen_loader` map creation generator
>     (`bpf_gen__map_create()`) completely omitted plumbing
>     `btf_vmlinux_value_type_id` because `attr_size` was calculated only up
>     to `map_extra` (which resides before `btf_vmlinux_value_type_id` in
>     `union bpf_attr`).

[Severity: High]
Is this description accurate regarding the layout of union bpf_attr?

Looking at the structure layout, map_extra is actually located immediately
after btf_vmlinux_value_type_id, not before it.

> diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
> index cd5c2543f54d8..27b0353d1082e 100644
> --- a/tools/lib/bpf/gen_loader.c
> +++ b/tools/lib/bpf/gen_loader.c
> @@ -507,7 +507,7 @@ void bpf_gen__map_create(struct bpf_gen *gen,
>  			 __u32 key_size, __u32 value_size, __u32 max_entries,
>  			 struct bpf_map_create_opts *map_attr, int map_idx)
>  {
> -	int attr_size = offsetofend(union bpf_attr, map_extra);
> +	int attr_size = offsetofend(union bpf_attr, btf_vmlinux_value_type_id);

[Severity: High]
Does this change silently truncate the map_extra field from the generated
system call arguments?

Since map_extra actually follows btf_vmlinux_value_type_id in union bpf_attr,
reducing attr_size to offsetofend(..., btf_vmlinux_value_type_id) completely
strips map_extra from the payload.

When add_data() copies attr_size bytes, the kernel will subsequently assume
map_extra is 0. This seems like it would break functionality for maps that
rely on map_extra when loaded via light skeletons, such as BPF_MAP_TYPE_ARENA
(where it represents the mmap address) and BPF_MAP_TYPE_BLOOM_FILTER (where
it specifies the number of hash functions).

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260526-libbpf-load-vmlinux-btf-in-gen_loader-mode-v2-0-6750f5859bc6@google.com?part=3

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-26 13:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-26 12:12 [PATCH v2 0/3] libbpf: support STRUCT_OPS in light skeletons Siddharth Nayyar
2026-05-26 12:12 ` [PATCH v2 1/3] libbpf: load vmlinux BTF in gen_loader mode for struct_ops Siddharth Nayyar
2026-05-26 12:12 ` [PATCH v2 2/3] libbpf: zero out btf_key_type_id for STRUCT_OPS maps Siddharth Nayyar
2026-05-26 12:12 ` [PATCH v2 3/3] libbpf: plumb btf_vmlinux_value_type_id and btf_fd in gen_loader Siddharth Nayyar
2026-05-26 13:57   ` sashiko-bot

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.