[RFC PATCH bpf-next 05/12] bpf: Collect SDT probe BTF IDs from BTF decl tags
From: Xu Kuohai
Date: Sat Jun 27 2026 - 10:57:45 EST
From: Xu Kuohai <xukuohai@xxxxxxxxxx>
Collect SDT probe BTF IDs from BTF decl tags matching name pattern
"bpf_sdt:<name>:<nargs>". The IDs are ultimately stored in each probe
entry of the SDT map.
Signed-off-by: Xu Kuohai <xukuohai@xxxxxxxxxx>
---
include/uapi/linux/bpf.h | 1 +
kernel/bpf/bpf_insn_array.c | 1 +
tools/include/uapi/linux/bpf.h | 1 +
tools/lib/bpf/libbpf.c | 55 ++++++++++++++++++++++++++++++++++
4 files changed, 58 insertions(+)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 6a03e3f0506e..773a7def0fbd 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -7739,6 +7739,7 @@ struct bpf_insn_array_value {
__u32 orig_off;
__u32 xlated_off;
__u32 jitted_off;
+ __u32 btf_id; /* BTF FUNC_PROTO type ID (0 if none) */
__u8 nargs; /* argument count (0..5) */
__u8 arg_reg[5]; /* BPF register for each argument */
__u8 pad[2];
diff --git a/kernel/bpf/bpf_insn_array.c b/kernel/bpf/bpf_insn_array.c
index f43777c5cd07..aca8676ab563 100644
--- a/kernel/bpf/bpf_insn_array.c
+++ b/kernel/bpf/bpf_insn_array.c
@@ -103,6 +103,7 @@ static long insn_array_update_elem(struct bpf_map *map, void *key, void *value,
insn_array->values[index].orig_off = val.orig_off;
if (insn_array->subtype == BPF_INSN_ARRAY_SUBTYPE_SDT) {
+ insn_array->values[index].btf_id = val.btf_id;
insn_array->values[index].nargs = val.nargs;
memcpy(insn_array->values[index].arg_reg, val.arg_reg, sizeof(val.arg_reg));
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 6a03e3f0506e..773a7def0fbd 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -7739,6 +7739,7 @@ struct bpf_insn_array_value {
__u32 orig_off;
__u32 xlated_off;
__u32 jitted_off;
+ __u32 btf_id; /* BTF FUNC_PROTO type ID (0 if none) */
__u8 nargs; /* argument count (0..5) */
__u8 arg_reg[5]; /* BPF register for each argument */
__u8 pad[2];
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 3f8b12a1eb8b..badac128e8ad 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -715,6 +715,7 @@ struct sdt_entry {
__u64 insn_idx; /* insn index of probe site within its ELF section */
__u8 nargs; /* how many arguments */
__u8 arg_reg[5]; /* which register the argument locates in */
+ __u32 btf_id; /* BTF FUNC_PROTO type ID from decl tag */
};
struct bpf_object {
@@ -6692,6 +6693,57 @@ static int create_jt_map(struct bpf_object *obj, struct bpf_program *prog, struc
return err;
}
+static void sdt_collect_btf_ids(struct bpf_object *obj)
+{
+ int n = btf__type_cnt(obj->btf);
+ const struct btf_type *t;
+ int i;
+
+ for (i = 1; i < n; i++) {
+ const char *tag, *colon;
+ size_t name_len;
+ __u32 func_proto_id;
+ int j;
+
+ t = btf_type_by_id(obj->btf, i);
+ if (!btf_is_decl_tag(t) || btf_decl_tag(t)->component_idx != -1)
+ continue;
+
+ tag = btf__str_by_offset(obj->btf, t->name_off);
+ if (strncmp(tag, "bpf_sdt:", 8) != 0)
+ continue;
+
+ /* tag format: "bpf_sdt:<name>:<nargs>"; <name> has no colons */
+ colon = strchr(tag + 8, ':');
+ if (!colon)
+ continue;
+ name_len = colon - tag - 8;
+
+ /* type chain: DECL_TAG -> VAR -> (CONST) -> PTR -> FUNC_PROTO */
+ t = btf_type_by_id(obj->btf, t->type);
+ if (!btf_is_var(t))
+ continue;
+ t = btf_type_by_id(obj->btf, t->type);
+ if (btf_kind(t) == BTF_KIND_CONST)
+ t = btf_type_by_id(obj->btf, t->type);
+ if (!btf_is_ptr(t))
+ continue;
+ func_proto_id = t->type;
+ t = btf_type_by_id(obj->btf, func_proto_id);
+ if (!btf_is_func_proto(t))
+ continue;
+
+ /* match by name (tag format: "bpf_sdt:<name>:<nargs>") */
+ for (j = 0; j < obj->sdt_entry_cnt; j++) {
+ struct sdt_entry *e = &obj->sdt_entries[j];
+
+ if (!e->btf_id && strlen(e->name) == name_len &&
+ strncmp(tag + 8, e->name, name_len) == 0)
+ e->btf_id = func_proto_id;
+ }
+ }
+}
+
static int bpf_object__resolve_sdt_progs(struct bpf_object *obj)
{
int i, j;
@@ -6749,6 +6801,8 @@ static int bpf_object__create_sdt_maps(struct bpf_object *obj)
if (err)
return err;
+ sdt_collect_btf_ids(obj);
+
prog_sdt = calloc(obj->nr_programs, sizeof(*prog_sdt));
if (!prog_sdt)
return -ENOMEM;
@@ -6785,6 +6839,7 @@ static int bpf_object__create_sdt_maps(struct bpf_object *obj)
key = prog_sdt[e->prog_idx].next_key++;
memset(&val, 0, sizeof(val));
+ val.btf_id = e->btf_id;
val.nargs = e->nargs;
val.orig_off = e->insn_idx - prog->sec_insn_off;
memcpy(val.arg_reg, e->arg_reg, sizeof(val.arg_reg));
--
2.47.3