1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef TRACEPOINT_DEFS_H 3 #define TRACEPOINT_DEFS_H 1 4 5 /* 6 * File can be included directly by headers who only want to access 7 * tracepoint->key to guard out of line trace calls, or the definition of 8 * trace_print_flags{_u64}. Otherwise linux/tracepoint.h should be used. 9 */ 10 11 #include <linux/atomic.h> 12 #include <linux/static_key.h> 13 14 struct static_call_key; 15 16 struct trace_print_flags { 17 unsigned long mask; 18 const char *name; 19 }; 20 21 struct trace_print_flags_u64 { 22 unsigned long long mask; 23 const char *name; 24 }; 25 26 struct tracepoint_func { 27 void *func; 28 void *data; 29 int prio; 30 }; 31 32 struct tracepoint_ext { 33 int (*regfunc)(void); 34 void (*unregfunc)(void); 35 /* Flags. */ 36 unsigned int faultable:1; 37 }; 38 39 struct tracepoint { 40 const char *name; /* Tracepoint name */ 41 struct static_key_false key; 42 struct static_call_key *static_call_key; 43 void *static_call_tramp; 44 void *iterator; 45 void *probestub; 46 struct tracepoint_func __rcu *funcs; 47 struct tracepoint_ext *ext; 48 }; 49 50 #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS 51 typedef const int tracepoint_ptr_t; 52 #else 53 typedef struct tracepoint * const tracepoint_ptr_t; 54 #endif 55 56 struct bpf_raw_event_map { 57 struct tracepoint *tp; 58 void *bpf_func; 59 u32 num_args; 60 u32 writable_size; 61 } __aligned(32); 62 63 /* 64 * If a tracepoint needs to be called from a header file, it is not 65 * recommended to call it directly, as tracepoints in header files 66 * may cause side-effects and bloat the kernel. Instead, use 67 * tracepoint_enabled() to test if the tracepoint is enabled, then if 68 * it is, call a wrapper function defined in a C file that will then 69 * call the tracepoint. 70 * 71 * For "trace_foo_bar()", you would need to create a wrapper function 72 * in a C file to call trace_foo_bar(): 73 * void do_trace_foo_bar(args) { trace_foo_bar(args); } 74 * Then in the header file, declare the tracepoint: 75 * DECLARE_TRACEPOINT(foo_bar); 76 * And call your wrapper: 77 * static inline void some_inlined_function() { 78 * [..] 79 * if (tracepoint_enabled(foo_bar)) 80 * do_trace_foo_bar(args); 81 * [..] 82 * } 83 * 84 * Note: tracepoint_enabled(foo_bar) is equivalent to trace_foo_bar_enabled() 85 * but is safe to have in headers, where trace_foo_bar_enabled() is not. 86 */ 87 #define DECLARE_TRACEPOINT(tp) \ 88 extern struct tracepoint __tracepoint_##tp 89 90 #ifdef CONFIG_TRACEPOINTS 91 # define tracepoint_enabled(tp) \ 92 static_branch_unlikely(&(__tracepoint_##tp).key) 93 #else 94 # define tracepoint_enabled(tracepoint) false 95 #endif 96 97 #endif 98