Re: [PATCH v2 01/19] tracepoint: Add trace_call__##name() API

2026-03-25 Thread Google
On Mon, 23 Mar 2026 12:00:20 -0400
"Vineeth Pillai (Google)"  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) 


> 
> 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 
> Suggested-by: Peter Zijlstra 
> Signed-off-by: Vineeth Pillai (Google) 
> 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
> 


-- 
Masami Hiramatsu (Google) 



[PATCH v2 01/19] tracepoint: Add trace_call__##name() API

2026-03-23 Thread Vineeth Pillai (Google)
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 */

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 
Suggested-by: Peter Zijlstra 
Signed-off-by: Vineeth Pillai (Google) 
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