Re: [RFC PATCH bpf-next 00/12] bpf: Introduce static-defined tracing probe for BPF

From: Xu Kuohai

Date: Tue Jun 30 2026 - 22:19:07 EST


On 7/1/2026 6:07 AM, Alexei Starovoitov wrote:
On Sat Jun 27, 2026 at 3:51 PM PDT, Xu Kuohai wrote:
From: Xu Kuohai <xukuohai@xxxxxxxxxx>

This series introduces static-defined tracing probes for BPF programs.
BPF SDT (static-defined tracing) works similarly to USDT. User defines
probes in the BPF source code. The probes are built into NOP instructions
in the ELF. At runtime, when an observer is attached, the NOP instruction
is patched to a CALL instruction to the observer prog trampoline.

Unlike USDT, BPF SDT requires explicit macros to generate the function
prototype BTF for each probe. This allows the verifier to validate the
probe sites against the declared types, and observer programs can be
attached similarly to normal tracing programs using the function prototype
information.

A probe with two arguments in the target program can be declared and defined
like:

BPF_SDT_DECLARE2(my_trace, int, int);

SEC("xdp")
int xdp_prog(struct xdp_md *ctx)
{
int len = ctx->data_end - ctx->data;
int ret = XDP_DROP;
...
BPF_SDT_PROBE2(my_trace, len, ret);
...
}

An observer would be like:

SEC("bpf_sdt")
int BPF_PROG(observer_prog, int len, int ret)
{
bpf_printk("len=%d ret=%d\n", len, ret);
return 0;
}

The target program and probe site for the observer program should be set
at load time via bpf_program__set_attach_target() manually, since program
names are not unique and program IDs are allocated at runtime - there is
no static way to identify the target program.

For BPF_SDT_DECLARE2(my_trace, int, int) and BPF_SDT_PROBE2(my_trace, len, ret)
macros, the compiler produces:

[code section, e.g. xdp]
goto +0 // NOP, patched to CALL at attach time

[.bpf_sdt_notes section]
___sdt_jt_my_trace: // symbol marking this entry's boundary
.quad 0b // 8 bytes: offset of the NOP in the code
// section (resolved by the linker via
// R_BPF_64_ABS64 relocation)
r1 = %[arg1_reg] // 8 bytes per argument: BPF move insn
// whose src_reg field encodes the BPF
// register holding each probe argument
r2 = %[arg2_reg]

....

[.BTF section]
FUNC_PROTO (int, int) -> void // from BPF_SDT_DECLARE2 stub
DECL_TAG "bpf_sdt:my_trace:2" // keyed by name + nargs

Interesting idea and encoding scheme, but I don't think we need it.
I'd rather see static_branch/jmp work that Anton started to be completed.
That would be more generic and folks that need SDT-like observability
inside bpf progs can instead guard their debug code with static_branches.
SDT equivalent would be static branch plus a call to nop function
which can be freplaced.

Sounds like this is similar to the kernel tracepoint approach. I'll
hold this work and recheck if a dedicated SDT-like function is still
needed once Anton's static key work is posted.