add a kfunc 'bpf_ptrace_vprintk' printing bpf msg with trace_marker format requirement so that these msgs can be retrieved by android perfetto by default and well represented in perfetto UI. [testing prog] const volatile bool ptrace_enabled = true; extern int bpf_ptrace_vprintk(char *fmt, u32 fmt_size, const void *args, u32 args__sz) __ksym; ({ \ if (!ptrace_enabled) { \ bpf_printk(fmt, __VA_ARGS__); \ } else { \ char __fmt[] = fmt; \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ u64 __params[] = { __VA_ARGS__ }; \ _Pragma("GCC diagnostic pop") \ bpf_ptrace_vprintk(__fmt, sizeof(__fmt), __params, sizeof(__params)); \ } \ }) SEC("perf_event") int do_sample(struct bpf_perf_event_data *ctx) { u64 ip = PT_REGS_IP(&ctx->regs); u64 id = bpf_get_current_pid_tgid(); s32 pid = id >> 32; s32 tid = id; debug_printk("N|%d|BPRF-%d|BPRF:%llx", pid, tid, ip); return 0; } [output]: app-3151 [000] d.h1. 6059.904239: tracing_mark_write: N|2491|BPRF-3151|BPRF:58750d0eec Signed-off-by: Eric Yan <eric.yan@xxxxxxxx> --- kernel/bpf/helpers.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 1a43d06eab28..e3d17d3b17c5 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -2521,6 +2521,39 @@ __bpf_kfunc struct task_struct *bpf_task_from_pid(s32 pid) return p; } +static noinline void tracing_mark_write(char *buf) +{ + trace_printk(buf); +} + +/** + * same as bpf_trace_vprintk, except for a trace_marker format requirement + */ +__bpf_kfunc int bpf_ptrace_vprintk(char *fmt, u32 fmt_size, const void *args, u32 args__sz) +{ + struct bpf_bprintf_data data = { + .get_bin_args = true, + .get_buf = true, + }; + int ret, num_args; + + if (args__sz & 7 || args__sz > MAX_BPRINTF_VARARGS * 8 || (args__sz && !args)) + return -EINVAL; + num_args = args__sz / 8; + + ret = bpf_bprintf_prepare(fmt, fmt_size, args, num_args, &data); + if (ret < 0) + return ret; + + ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args); + + tracing_mark_write(data.buf); + + bpf_bprintf_cleanup(&data); + + return ret; +} + /** * bpf_dynptr_slice() - Obtain a read-only pointer to the dynptr data. * @p: The dynptr whose data slice to retrieve @@ -3090,6 +3123,7 @@ BTF_ID_FLAGS(func, bpf_iter_bits_new, KF_ITER_NEW) BTF_ID_FLAGS(func, bpf_iter_bits_next, KF_ITER_NEXT | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_iter_bits_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_copy_from_user_str, KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_ptrace_vprintk) BTF_KFUNCS_END(common_btf_ids) static const struct btf_kfunc_id_set common_kfunc_set = { -- 2.34.1