B4/generic tracepoint#12118
Draft
mykyta5 wants to merge 5 commits into
Draft
Conversation
BPF and other consumers that want to attach to or decode a generic
tracepoint need three pieces of BTF information for it:
- the BTF of the object that owns the tracepoint's types
- the FUNC_PROTO describing the tracepoint arguments (with names),
consumed by raw_tp / tp_btf BPF programs
- the STRUCT id of trace_event_raw_<call>, the ring-buffer record
consumed by classic BPF_PROG_TYPE_TRACEPOINT programs
Today none of this is easily discoverable from userspace. The kernel
knows the ids - resolve_btfids fills them in at link time - but
consumers have to search them by the naming convention
("__bpf_trace_<name>", "trace_event_raw_<name>"), walking BTF for
every tracepoint.
This series stores those ids in trace_event_class and exposes them
via events/<sys>/<event>/btf_ids, e.g.
# cat /sys/kernel/tracing/events/sched/sched_switch/btf_ids
btf_obj_id: 1
raw_btf_id: 28882
tp_btf_id: 106335
# bpftool btf dump id 1 root_id 28882 format raw
[28882] FUNC_PROTO '(anon)' ret_type_id=0 vlen=5
'__data' type_id=9
'preempt' type_id=60674
'prev' type_id=219
'next' type_id=219
'prev_state' type_id=108689
# bpftool btf dump id 1 root_id 106335 format raw
[106335] STRUCT 'trace_event_raw_sched_switch' size=64 vlen=9
'ent' type_id=104654 bits_offset=0
'prev_comm' type_id=580 bits_offset=64
'prev_pid' type_id=92875 bits_offset=192
'prev_prio' type_id=79365 bits_offset=224
'prev_state' type_id=83958 bits_offset=256
'next_comm' type_id=580 bits_offset=320
'next_pid' type_id=92875 bits_offset=448
'next_prio' type_id=79365 bits_offset=480
'__data' type_id=407 bits_offset=512
For per-syscall events (all sharing the same dispatcher), raw_btf_id
is 0 — raw_tp / tp_btf programs attach to raw_syscalls/sys_{enter,exit},
not per-syscall events:
# cat /sys/kernel/tracing/events/syscalls/sys_enter_write/btf_ids
btf_obj_id: 1
raw_btf_id: 0
tp_btf_id: 106540
This unlocks few usecases for consumers:
- Resolving tp_btf attach targets and argument types directly,
instead of constructing "__bpf_trace_*" names and
re-discovering them in vmlinux BTF.
- Get a stable, machine-readable contract for tracepoint payloads,
with field names preserved.
Patch 1 exports the two BTF helpers the tracing core needs.
Patch 2 wires DECLARE_EVENT_CLASS to publish the ids, adds the tracefs
reader, and wires the syscall classes so per-syscall events
carry tp_btf_id (raw_btf_id is 0 there — see above).
Patch 3 adds a selftest covering the sched_switch tracepoint.
Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
---
Changes in v2:
- kernel/bpf/btf.c: dropped both EXPORT_SYMBOL_GPL()
- kernel/trace/trace_events.c (event_btf_ids_read):
replaced guard(mutex)(&event_mutex) with explicit
mutex_lock/mutex_unlock. scnprintf() and simple_read_from_buffer()
(which calls copy_to_user()) now run outside the lock work.
- tools/testing/selftests/bpf/prog_tests/tp_btf_ids.c:
- Added if (!env.has_testmod) { test__skip(); return; } at the top of
test_tp_btf_ids() so the test skips gracefully when bpf_testmod.ko
is absent.
- Wrapped ASSERT_EQ(btf_vlen(proto_t), 3, ...) with if (!...) goto out;
to prevent OOB read of params[2].
- Added if (!ASSERT_GE(btf_vlen(rec_t), 5, ...)) goto out; before reading
members[0..4].
- Link to v1: https://patch.msgid.link/20260515-generic_tracepoint-v1-0-aa619fa94132@meta.com
--- b4-submit-tracking ---
{
"series": {
"revision": 2,
"change-id": "20260508-generic_tracepoint-d488a5a7ab18",
"prefixes": [
"bpf-next"
],
"history": {
"v1": [
"20260515-generic_tracepoint-v1-0-aa619fa94132@meta.com"
]
}
}
}
Drop the static qualifier and add prototypes to <linux/btf.h> so the tracing core can look up module BTF and translate ids stored by resolve_btfids (which are local to a module's split BTF) into the runtime ids used by the kernel. Used by the upcoming events/<sys>/<event>/btf_ids tracefs interface. Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
Add events/<sys>/<event>/btf_ids, a per-template file that exposes
the BTF ids resolve_btfids fills in for each tracepoint:
btf_obj_id BTF object owning the ids below
raw_btf_id FUNC_PROTO of __bpf_trace_<call> (named args), consumed
by raw_tp / tp_btf BPF programs
tp_btf_id trace_event_raw_<call> ring-buffer record, consumed by
classic BPF_PROG_TYPE_TRACEPOINT programs
DECLARE_EVENT_CLASS now emits a 2-entry BTF_ID_LIST (FUNC __bpf_trace_*
and STRUCT trace_event_raw_*) and stores the pointer in
trace_event_class.
Per-syscall events under syscalls/ share the handcrafted classes
event_class_syscall_{enter,exit} instead of going through
DECLARE_EVENT_CLASS. Wire those classes to the BTF id lists
generated for sys_enter / sys_exit so all ~700 per-syscall
events expose the shared dispatcher prototype and record.
The per-syscall events do not own their own tracepoint
(they share sys_enter/sys_exit), so raw_btf_id is reported as 0
on those events; the meaningful raw_btf_id is exposed on
raw_syscalls/sys_{enter,exit}/btf_ids where raw_tp / tp_btf
programs can actually attach.
Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
Read events/bpf_testmod/bpf_testmod_test_read/btf_ids and verify the exported FUNC_PROTO matches the testmod tracepoint signature (__data, struct task_struct *task, struct bpf_testmod_test_read_ctx *ctx) and the record struct trace_event_raw_bpf_testmod_test_read carries the fields declared by TP_STRUCT__entry. Use the testmod tracepoint so the test exercises the module/split-BTF path (btf_relocate_id) rather than vmlinux only, and falls back from /sys/kernel/tracing to /sys/kernel/debug/tracing when tracefs is not mounted at the new location. Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
3de8a1c to
8be0732
Compare
ec31e3e to
b3beebb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.