On Mon, 23 Mar 2026 12:00:20 -0400 "Vineeth Pillai (Google)" vineeth@bitbyteword.org wrote:
Add trace_call__##name() as a companion to trace_##name(). When a caller already guards a tracepoint with an explicit enabled check:
if (trace_foo_enabled() && cond) trace_foo(args);
trace_foo() internally repeats the static_branch_unlikely() test, which the compiler cannot fold since static branches are patched binary instructions. This results in two static-branch evaluations for every guarded call site.
trace_call__##name() calls __do_trace_##name() directly, skipping the redundant static-branch re-check. This avoids leaking the internal __do_trace_##name() symbol into call sites while still eliminating the double evaluation:
if (trace_foo_enabled() && cond) trace_invoke_foo(args); /* calls __do_trace_foo() directly */
nit: trace_call_foo() instead of trace_invoke_foo()?
Anyway looks good to me.
Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org
Three locations are updated:
- __DECLARE_TRACE: invoke form omits static_branch_unlikely, retains the LOCKDEP RCU-watching assertion.
- __DECLARE_TRACE_SYSCALL: same, plus retains might_fault().
- !TRACEPOINTS_ENABLED stub: empty no-op so callers compile cleanly when tracepoints are compiled out.
Suggested-by: Steven Rostedt rostedt@goodmis.org Suggested-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Vineeth Pillai (Google) vineeth@bitbyteword.org Assisted-by: Claude:claude-sonnet-4-6
include/linux/tracepoint.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 22ca1c8b54f32..ed969705341f1 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -294,6 +294,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) WARN_ONCE(!rcu_is_watching(), \ "RCU not watching for tracepoint"); \ } \
- } \
- static inline void trace_call__##name(proto) \
- { \
}__do_trace_##name(args); \#define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \ @@ -313,6 +317,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) WARN_ONCE(!rcu_is_watching(), \ "RCU not watching for tracepoint"); \ } \
- } \
- static inline void trace_call__##name(proto) \
- { \
might_fault(); \ }__do_trace_##name(args); \/* @@ -398,6 +407,8 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) #define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \ static inline void trace_##name(proto) \ { } \
- static inline void trace_call__##name(proto) \
- { } \ static inline int \ register_trace_##name(void (*probe)(data_proto), \ void *data) \
-- 2.53.0