152a6e82aSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
297e1c18eSMathieu Desnoyers #ifndef _LINUX_TRACEPOINT_H
397e1c18eSMathieu Desnoyers #define _LINUX_TRACEPOINT_H
497e1c18eSMathieu Desnoyers
597e1c18eSMathieu Desnoyers /*
697e1c18eSMathieu Desnoyers * Kernel Tracepoint API.
797e1c18eSMathieu Desnoyers *
8ec15872dSMauro Carvalho Chehab * See Documentation/trace/tracepoints.rst.
997e1c18eSMathieu Desnoyers *
10de7b2973SMathieu Desnoyers * Copyright (C) 2008-2014 Mathieu Desnoyers <[email protected]>
1197e1c18eSMathieu Desnoyers *
1297e1c18eSMathieu Desnoyers * Heavily inspired from the Linux Kernel Markers.
1397e1c18eSMathieu Desnoyers */
1497e1c18eSMathieu Desnoyers
15f3775549SSteven Rostedt (Red Hat) #include <linux/smp.h>
16e6753f23SJoel Fernandes (Google) #include <linux/srcu.h>
17b70e4f05SWu Zhangjin #include <linux/errno.h>
1897e1c18eSMathieu Desnoyers #include <linux/types.h>
1997e1c18eSMathieu Desnoyers #include <linux/rcupdate.h>
20a363d27cSMathieu Desnoyers #include <linux/rcupdate_trace.h>
21bd2a634dSAndi Kleen #include <linux/tracepoint-defs.h>
22d25e37d8SSteven Rostedt (VMware) #include <linux/static_call.h>
2397e1c18eSMathieu Desnoyers
2497e1c18eSMathieu Desnoyers struct module;
2597e1c18eSMathieu Desnoyers struct tracepoint;
26de7b2973SMathieu Desnoyers struct notifier_block;
2797e1c18eSMathieu Desnoyers
2800f4b652SJeremy Linton struct trace_eval_map {
290c564a53SSteven Rostedt (Red Hat) const char *system;
3000f4b652SJeremy Linton const char *eval_string;
3100f4b652SJeremy Linton unsigned long eval_value;
320c564a53SSteven Rostedt (Red Hat) };
330c564a53SSteven Rostedt (Red Hat)
347904b5c4SSteven Rostedt (Red Hat) #define TRACEPOINT_DEFAULT_PRIO 10
357904b5c4SSteven Rostedt (Red Hat)
3638516ab5SSteven Rostedt extern int
37de7b2973SMathieu Desnoyers tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
38de7b2973SMathieu Desnoyers extern int
397904b5c4SSteven Rostedt (Red Hat) tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data,
407904b5c4SSteven Rostedt (Red Hat) int prio);
417904b5c4SSteven Rostedt (Red Hat) extern int
429913d574SSteven Rostedt (VMware) tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data,
439913d574SSteven Rostedt (VMware) int prio);
449913d574SSteven Rostedt (VMware) extern int
45de7b2973SMathieu Desnoyers tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);
469913d574SSteven Rostedt (VMware) static inline int
tracepoint_probe_register_may_exist(struct tracepoint * tp,void * probe,void * data)479913d574SSteven Rostedt (VMware) tracepoint_probe_register_may_exist(struct tracepoint *tp, void *probe,
489913d574SSteven Rostedt (VMware) void *data)
499913d574SSteven Rostedt (VMware) {
509913d574SSteven Rostedt (VMware) return tracepoint_probe_register_prio_may_exist(tp, probe, data,
519913d574SSteven Rostedt (VMware) TRACEPOINT_DEFAULT_PRIO);
529913d574SSteven Rostedt (VMware) }
53de7b2973SMathieu Desnoyers extern void
54de7b2973SMathieu Desnoyers for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv),
55de7b2973SMathieu Desnoyers void *priv);
562e26ca71SSteven Rostedt
57b75ef8b4SMathieu Desnoyers #ifdef CONFIG_MODULES
58b75ef8b4SMathieu Desnoyers struct tp_module {
59b75ef8b4SMathieu Desnoyers struct list_head list;
60eb7d035cSSteven Rostedt (Red Hat) struct module *mod;
61b75ef8b4SMathieu Desnoyers };
62de7b2973SMathieu Desnoyers
6345ab2813SSteven Rostedt (Red Hat) bool trace_module_has_bad_taint(struct module *mod);
64de7b2973SMathieu Desnoyers extern int register_tracepoint_module_notifier(struct notifier_block *nb);
65de7b2973SMathieu Desnoyers extern int unregister_tracepoint_module_notifier(struct notifier_block *nb);
66d4df54f3SMasami Hiramatsu (Google) void for_each_module_tracepoint(void (*fct)(struct tracepoint *,
67d4df54f3SMasami Hiramatsu (Google) struct module *, void *),
68d4df54f3SMasami Hiramatsu (Google) void *priv);
69d4df54f3SMasami Hiramatsu (Google) void for_each_tracepoint_in_module(struct module *,
70d4df54f3SMasami Hiramatsu (Google) void (*fct)(struct tracepoint *,
71d4df54f3SMasami Hiramatsu (Google) struct module *, void *),
72d5dbf8b4SMasami Hiramatsu (Google) void *priv);
7345ab2813SSteven Rostedt (Red Hat) #else
trace_module_has_bad_taint(struct module * mod)7445ab2813SSteven Rostedt (Red Hat) static inline bool trace_module_has_bad_taint(struct module *mod)
7545ab2813SSteven Rostedt (Red Hat) {
7645ab2813SSteven Rostedt (Red Hat) return false;
7745ab2813SSteven Rostedt (Red Hat) }
78de7b2973SMathieu Desnoyers static inline
register_tracepoint_module_notifier(struct notifier_block * nb)79de7b2973SMathieu Desnoyers int register_tracepoint_module_notifier(struct notifier_block *nb)
80de7b2973SMathieu Desnoyers {
81de7b2973SMathieu Desnoyers return 0;
82de7b2973SMathieu Desnoyers }
83de7b2973SMathieu Desnoyers static inline
unregister_tracepoint_module_notifier(struct notifier_block * nb)84de7b2973SMathieu Desnoyers int unregister_tracepoint_module_notifier(struct notifier_block *nb)
85de7b2973SMathieu Desnoyers {
86de7b2973SMathieu Desnoyers return 0;
87de7b2973SMathieu Desnoyers }
88d5dbf8b4SMasami Hiramatsu (Google) static inline
for_each_module_tracepoint(void (* fct)(struct tracepoint *,struct module *,void *),void * priv)89d4df54f3SMasami Hiramatsu (Google) void for_each_module_tracepoint(void (*fct)(struct tracepoint *,
90d4df54f3SMasami Hiramatsu (Google) struct module *, void *),
91d4df54f3SMasami Hiramatsu (Google) void *priv)
92d4df54f3SMasami Hiramatsu (Google) {
93d4df54f3SMasami Hiramatsu (Google) }
94d4df54f3SMasami Hiramatsu (Google) static inline
for_each_tracepoint_in_module(struct module * mod,void (* fct)(struct tracepoint *,struct module *,void *),void * priv)95d4df54f3SMasami Hiramatsu (Google) void for_each_tracepoint_in_module(struct module *mod,
96d4df54f3SMasami Hiramatsu (Google) void (*fct)(struct tracepoint *,
97d4df54f3SMasami Hiramatsu (Google) struct module *, void *),
98d5dbf8b4SMasami Hiramatsu (Google) void *priv)
99d5dbf8b4SMasami Hiramatsu (Google) {
100d5dbf8b4SMasami Hiramatsu (Google) }
101b75ef8b4SMathieu Desnoyers #endif /* CONFIG_MODULES */
102b75ef8b4SMathieu Desnoyers
1032e26ca71SSteven Rostedt /*
1042e26ca71SSteven Rostedt * tracepoint_synchronize_unregister must be called between the last tracepoint
1052e26ca71SSteven Rostedt * probe unregistration and the end of module exit to make sure there is no
1062e26ca71SSteven Rostedt * caller executing a probe when it is freed.
107654ced4aSMathieu Desnoyers *
108654ced4aSMathieu Desnoyers * An alternative is to use the following for batch reclaim associated
109654ced4aSMathieu Desnoyers * with a given tracepoint:
110654ced4aSMathieu Desnoyers *
111654ced4aSMathieu Desnoyers * - tracepoint_is_faultable() == false: call_rcu()
112654ced4aSMathieu Desnoyers * - tracepoint_is_faultable() == true: call_rcu_tasks_trace()
1132e26ca71SSteven Rostedt */
114e6753f23SJoel Fernandes (Google) #ifdef CONFIG_TRACEPOINTS
tracepoint_synchronize_unregister(void)1152e26ca71SSteven Rostedt static inline void tracepoint_synchronize_unregister(void)
1162e26ca71SSteven Rostedt {
117a363d27cSMathieu Desnoyers synchronize_rcu_tasks_trace();
11874401729SPaul E. McKenney synchronize_rcu();
1192e26ca71SSteven Rostedt }
tracepoint_is_faultable(struct tracepoint * tp)120654ced4aSMathieu Desnoyers static inline bool tracepoint_is_faultable(struct tracepoint *tp)
121654ced4aSMathieu Desnoyers {
122654ced4aSMathieu Desnoyers return tp->ext && tp->ext->faultable;
123654ced4aSMathieu Desnoyers }
124e6753f23SJoel Fernandes (Google) #else
tracepoint_synchronize_unregister(void)125e6753f23SJoel Fernandes (Google) static inline void tracepoint_synchronize_unregister(void)
126e6753f23SJoel Fernandes (Google) { }
tracepoint_is_faultable(struct tracepoint * tp)127654ced4aSMathieu Desnoyers static inline bool tracepoint_is_faultable(struct tracepoint *tp)
128654ced4aSMathieu Desnoyers {
129654ced4aSMathieu Desnoyers return false;
130654ced4aSMathieu Desnoyers }
131e6753f23SJoel Fernandes (Google) #endif
1322e26ca71SSteven Rostedt
133b725dfeaSMathieu Desnoyers #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
1348cf868afSSteven Rostedt (Red Hat) extern int syscall_regfunc(void);
135b725dfeaSMathieu Desnoyers extern void syscall_unregfunc(void);
136b725dfeaSMathieu Desnoyers #endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */
137b725dfeaSMathieu Desnoyers
138d25e37d8SSteven Rostedt (VMware) #ifndef PARAMS
1392e26ca71SSteven Rostedt #define PARAMS(args...) args
140d25e37d8SSteven Rostedt (VMware) #endif
1412e26ca71SSteven Rostedt
1420c564a53SSteven Rostedt (Red Hat) #define TRACE_DEFINE_ENUM(x)
1434f0dfd76SJeremy Linton #define TRACE_DEFINE_SIZEOF(x)
1440c564a53SSteven Rostedt (Red Hat)
1459c0be3f6SMathieu Desnoyers #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
tracepoint_ptr_deref(tracepoint_ptr_t * p)1469c0be3f6SMathieu Desnoyers static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
1479c0be3f6SMathieu Desnoyers {
1489c0be3f6SMathieu Desnoyers return offset_to_ptr(p);
1499c0be3f6SMathieu Desnoyers }
1509c0be3f6SMathieu Desnoyers
1519c0be3f6SMathieu Desnoyers #define __TRACEPOINT_ENTRY(name) \
1529c0be3f6SMathieu Desnoyers asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \
1539c0be3f6SMathieu Desnoyers " .balign 4 \n" \
1549c0be3f6SMathieu Desnoyers " .long __tracepoint_" #name " - . \n" \
1559c0be3f6SMathieu Desnoyers " .previous \n")
1569c0be3f6SMathieu Desnoyers #else
tracepoint_ptr_deref(tracepoint_ptr_t * p)1579c0be3f6SMathieu Desnoyers static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
1589c0be3f6SMathieu Desnoyers {
1599c0be3f6SMathieu Desnoyers return *p;
1609c0be3f6SMathieu Desnoyers }
1619c0be3f6SMathieu Desnoyers
1629c0be3f6SMathieu Desnoyers #define __TRACEPOINT_ENTRY(name) \
1639c0be3f6SMathieu Desnoyers static tracepoint_ptr_t __tracepoint_ptr_##name __used \
16433def849SJoe Perches __section("__tracepoints_ptrs") = &__tracepoint_##name
1659c0be3f6SMathieu Desnoyers #endif
1669c0be3f6SMathieu Desnoyers
1672e26ca71SSteven Rostedt #endif /* _LINUX_TRACEPOINT_H */
1682e26ca71SSteven Rostedt
1692e26ca71SSteven Rostedt /*
1702e26ca71SSteven Rostedt * Note: we keep the TRACE_EVENT and DECLARE_TRACE outside the include
1712e26ca71SSteven Rostedt * file ifdef protection.
1722e26ca71SSteven Rostedt * This is due to the way trace events work. If a file includes two
1732e26ca71SSteven Rostedt * trace event headers under one "CREATE_TRACE_POINTS" the first include
1742e26ca71SSteven Rostedt * will override the TRACE_EVENT and break the second include.
1752e26ca71SSteven Rostedt */
1762e26ca71SSteven Rostedt
177ea20d929SSteven Rostedt #ifndef DECLARE_TRACE
178ea20d929SSteven Rostedt
1792939b046SSteven Rostedt #define TP_PROTO(args...) args
1802939b046SSteven Rostedt #define TP_ARGS(args...) args
181287050d3SSteven Rostedt #define TP_CONDITION(args...) args
18297e1c18eSMathieu Desnoyers
183c63b7682STal Shorer /*
184c63b7682STal Shorer * Individual subsystem my have a separate configuration to
185c63b7682STal Shorer * enable their tracepoints. By default, this file will create
186170ab26bSLi zeming * the tracepoints if CONFIG_TRACEPOINTS is defined. If a subsystem
187c63b7682STal Shorer * wants to be able to disable its tracepoints from being created
188c63b7682STal Shorer * it can define NOTRACE before including the tracepoint headers.
189c63b7682STal Shorer */
190c63b7682STal Shorer #if defined(CONFIG_TRACEPOINTS) && !defined(NOTRACE)
191c63b7682STal Shorer #define TRACEPOINTS_ENABLED
192c63b7682STal Shorer #endif
193c63b7682STal Shorer
194c63b7682STal Shorer #ifdef TRACEPOINTS_ENABLED
19597e1c18eSMathieu Desnoyers
196d25e37d8SSteven Rostedt (VMware) #ifdef CONFIG_HAVE_STATIC_CALL
197d9a1be1bSSteven Rostedt (VMware) #define __DO_TRACE_CALL(name, args) \
198d9a1be1bSSteven Rostedt (VMware) do { \
199d9a1be1bSSteven Rostedt (VMware) struct tracepoint_func *it_func_ptr; \
200d9a1be1bSSteven Rostedt (VMware) void *__data; \
201d9a1be1bSSteven Rostedt (VMware) it_func_ptr = \
202d9a1be1bSSteven Rostedt (VMware) rcu_dereference_raw((&__tracepoint_##name)->funcs); \
203d9a1be1bSSteven Rostedt (VMware) if (it_func_ptr) { \
204d9a1be1bSSteven Rostedt (VMware) __data = (it_func_ptr)->data; \
205d9a1be1bSSteven Rostedt (VMware) static_call(tp_func_##name)(__data, args); \
206d9a1be1bSSteven Rostedt (VMware) } \
207d9a1be1bSSteven Rostedt (VMware) } while (0)
208d25e37d8SSteven Rostedt (VMware) #else
209d9a1be1bSSteven Rostedt (VMware) #define __DO_TRACE_CALL(name, args) __traceiter_##name(NULL, args)
210d25e37d8SSteven Rostedt (VMware) #endif /* CONFIG_HAVE_STATIC_CALL */
211d25e37d8SSteven Rostedt (VMware)
21297e1c18eSMathieu Desnoyers /*
213ad37bcd9SAlice Ryhl * Declare an exported function that Rust code can call to trigger this
214ad37bcd9SAlice Ryhl * tracepoint. This function does not include the static branch; that is done
215ad37bcd9SAlice Ryhl * in Rust to avoid a function call when the tracepoint is disabled.
216ad37bcd9SAlice Ryhl */
217ad37bcd9SAlice Ryhl #define DEFINE_RUST_DO_TRACE(name, proto, args)
218ad37bcd9SAlice Ryhl #define __DEFINE_RUST_DO_TRACE(name, proto, args) \
219ad37bcd9SAlice Ryhl notrace void rust_do_trace_##name(proto) \
220ad37bcd9SAlice Ryhl { \
221*cff6d93eSAlice Ryhl __do_trace_##name(args); \
222ad37bcd9SAlice Ryhl }
223ad37bcd9SAlice Ryhl
224ad37bcd9SAlice Ryhl /*
22597e1c18eSMathieu Desnoyers * Make sure the alignment of the structure in the __tracepoints section will
22697e1c18eSMathieu Desnoyers * not add unwanted padding between the beginning of the section and the
22797e1c18eSMathieu Desnoyers * structure. Force alignment to the same alignment as the section start.
2283a630178SDave Hansen *
229c2679254SSteven Rostedt (Google) * When lockdep is enabled, we make sure to always test if RCU is
230c2679254SSteven Rostedt (Google) * "watching" regardless if the tracepoint is enabled or not. Tracepoints
231c2679254SSteven Rostedt (Google) * require RCU to be active, and it should always warn at the tracepoint
232c2679254SSteven Rostedt (Google) * site if it is not watching, as it will need to be active when the
233c2679254SSteven Rostedt (Google) * tracepoint is enabled.
23497e1c18eSMathieu Desnoyers */
235ef0d4186SMathieu Desnoyers #define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \
236de394e75S[email protected] extern int __traceiter_##name(data_proto); \
237de394e75S[email protected] DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
2387e066fb8SMathieu Desnoyers extern struct tracepoint __tracepoint_##name; \
239ad37bcd9SAlice Ryhl extern void rust_do_trace_##name(proto); \
24038516ab5SSteven Rostedt static inline int \
24138516ab5SSteven Rostedt register_trace_##name(void (*probe)(data_proto), void *data) \
24297e1c18eSMathieu Desnoyers { \
243de7b2973SMathieu Desnoyers return tracepoint_probe_register(&__tracepoint_##name, \
244de7b2973SMathieu Desnoyers (void *)probe, data); \
24597e1c18eSMathieu Desnoyers } \
24638516ab5SSteven Rostedt static inline int \
2477904b5c4SSteven Rostedt (Red Hat) register_trace_prio_##name(void (*probe)(data_proto), void *data,\
2487904b5c4SSteven Rostedt (Red Hat) int prio) \
2497904b5c4SSteven Rostedt (Red Hat) { \
2507904b5c4SSteven Rostedt (Red Hat) return tracepoint_probe_register_prio(&__tracepoint_##name, \
2517904b5c4SSteven Rostedt (Red Hat) (void *)probe, data, prio); \
2527904b5c4SSteven Rostedt (Red Hat) } \
2537904b5c4SSteven Rostedt (Red Hat) static inline int \
25438516ab5SSteven Rostedt unregister_trace_##name(void (*probe)(data_proto), void *data) \
25597e1c18eSMathieu Desnoyers { \
256de7b2973SMathieu Desnoyers return tracepoint_probe_unregister(&__tracepoint_##name,\
257de7b2973SMathieu Desnoyers (void *)probe, data); \
25853da59aaSMathieu Desnoyers } \
25938516ab5SSteven Rostedt static inline void \
26038516ab5SSteven Rostedt check_trace_callback_type_##name(void (*cb)(data_proto)) \
26153da59aaSMathieu Desnoyers { \
2627c65bbc7SSteven Rostedt (Red Hat) } \
2637c65bbc7SSteven Rostedt (Red Hat) static inline bool \
2647c65bbc7SSteven Rostedt (Red Hat) trace_##name##_enabled(void) \
2657c65bbc7SSteven Rostedt (Red Hat) { \
2664a8840afSJosh Poimboeuf return static_branch_unlikely(&__tracepoint_##name.key);\
26797e1c18eSMathieu Desnoyers }
26897e1c18eSMathieu Desnoyers
2690e6caab8SMathieu Desnoyers #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
270ef0d4186SMathieu Desnoyers __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \
271*cff6d93eSAlice Ryhl static inline void __do_trace_##name(proto) \
272ad37bcd9SAlice Ryhl { \
2737af08b57SLinus Torvalds if (cond) { \
2747af08b57SLinus Torvalds guard(preempt_notrace)(); \
2757af08b57SLinus Torvalds __DO_TRACE_CALL(name, TP_ARGS(args)); \
2767af08b57SLinus Torvalds } \
277ad37bcd9SAlice Ryhl } \
2780e6caab8SMathieu Desnoyers static inline void trace_##name(proto) \
2790e6caab8SMathieu Desnoyers { \
280*cff6d93eSAlice Ryhl if (static_branch_unlikely(&__tracepoint_##name.key)) \
281*cff6d93eSAlice Ryhl __do_trace_##name(args); \
2820e6caab8SMathieu Desnoyers if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
2830e6caab8SMathieu Desnoyers WARN_ONCE(!rcu_is_watching(), \
2840e6caab8SMathieu Desnoyers "RCU not watching for tracepoint"); \
2850e6caab8SMathieu Desnoyers } \
2860e6caab8SMathieu Desnoyers }
2870e6caab8SMathieu Desnoyers
288ef0d4186SMathieu Desnoyers #define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \
289ef0d4186SMathieu Desnoyers __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \
290*cff6d93eSAlice Ryhl static inline void __do_trace_##name(proto) \
291ad37bcd9SAlice Ryhl { \
2927af08b57SLinus Torvalds guard(rcu_tasks_trace)(); \
2937af08b57SLinus Torvalds __DO_TRACE_CALL(name, TP_ARGS(args)); \
294ad37bcd9SAlice Ryhl } \
2950e6caab8SMathieu Desnoyers static inline void trace_##name(proto) \
2960e6caab8SMathieu Desnoyers { \
297ee3685a9SMathieu Desnoyers might_fault(); \
298*cff6d93eSAlice Ryhl if (static_branch_unlikely(&__tracepoint_##name.key)) \
299*cff6d93eSAlice Ryhl __do_trace_##name(args); \
300ef0d4186SMathieu Desnoyers if (IS_ENABLED(CONFIG_LOCKDEP)) { \
3010e6caab8SMathieu Desnoyers WARN_ONCE(!rcu_is_watching(), \
3020e6caab8SMathieu Desnoyers "RCU not watching for tracepoint"); \
3030e6caab8SMathieu Desnoyers } \
3040e6caab8SMathieu Desnoyers }
3050e6caab8SMathieu Desnoyers
30665498646SMathieu Desnoyers /*
30765498646SMathieu Desnoyers * We have no guarantee that gcc and the linker won't up-align the tracepoint
30865498646SMathieu Desnoyers * structures, so we create an array of pointers that will be used for iteration
30965498646SMathieu Desnoyers * on the tracepoints.
310306d40aaSMathieu Desnoyers *
311306d40aaSMathieu Desnoyers * it_func[0] is never NULL because there is at least one element in the array
312306d40aaSMathieu Desnoyers * when the array itself is non NULL.
31365498646SMathieu Desnoyers */
314a9cfb877SMathieu Desnoyers #define __DEFINE_TRACE_EXT(_name, _ext, proto, args) \
315d25e37d8SSteven Rostedt (VMware) static const char __tpstrtab_##_name[] \
31633def849SJoe Perches __section("__tracepoints_strings") = #_name; \
317d25e37d8SSteven Rostedt (VMware) extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \
318de394e75S[email protected] int __traceiter_##_name(void *__data, proto); \
319e2d0d7b2SMasami Hiramatsu (Google) void __probestub_##_name(void *__data, proto); \
320d25e37d8SSteven Rostedt (VMware) struct tracepoint __tracepoint_##_name __used \
32133def849SJoe Perches __section("__tracepoints") = { \
322d25e37d8SSteven Rostedt (VMware) .name = __tpstrtab_##_name, \
3234a8840afSJosh Poimboeuf .key = STATIC_KEY_FALSE_INIT, \
324d25e37d8SSteven Rostedt (VMware) .static_call_key = &STATIC_CALL_KEY(tp_func_##_name), \
325d25e37d8SSteven Rostedt (VMware) .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
326de394e75S[email protected] .iterator = &__traceiter_##_name, \
327e2d0d7b2SMasami Hiramatsu (Google) .probestub = &__probestub_##_name, \
328a9cfb877SMathieu Desnoyers .funcs = NULL, \
329a9cfb877SMathieu Desnoyers .ext = _ext, \
330a9cfb877SMathieu Desnoyers }; \
331d25e37d8SSteven Rostedt (VMware) __TRACEPOINT_ENTRY(_name); \
332de394e75S[email protected] int __traceiter_##_name(void *__data, proto) \
333d25e37d8SSteven Rostedt (VMware) { \
334d25e37d8SSteven Rostedt (VMware) struct tracepoint_func *it_func_ptr; \
335d25e37d8SSteven Rostedt (VMware) void *it_func; \
336d25e37d8SSteven Rostedt (VMware) \
337d25e37d8SSteven Rostedt (VMware) it_func_ptr = \
338d25e37d8SSteven Rostedt (VMware) rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
339c8b186a8SAlexey Kardashevskiy if (it_func_ptr) { \
340d25e37d8SSteven Rostedt (VMware) do { \
3417211f0a2SSteven Rostedt (VMware) it_func = READ_ONCE((it_func_ptr)->func); \
342d25e37d8SSteven Rostedt (VMware) __data = (it_func_ptr)->data; \
343d25e37d8SSteven Rostedt (VMware) ((void(*)(void *, proto))(it_func))(__data, args); \
344d25e37d8SSteven Rostedt (VMware) } while ((++it_func_ptr)->func); \
345c8b186a8SAlexey Kardashevskiy } \
346d25e37d8SSteven Rostedt (VMware) return 0; \
347d25e37d8SSteven Rostedt (VMware) } \
348e2d0d7b2SMasami Hiramatsu (Google) void __probestub_##_name(void *__data, proto) \
349e2d0d7b2SMasami Hiramatsu (Google) { \
350e2d0d7b2SMasami Hiramatsu (Google) } \
351ad37bcd9SAlice Ryhl DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); \
352ad37bcd9SAlice Ryhl DEFINE_RUST_DO_TRACE(_name, TP_PROTO(proto), TP_ARGS(args))
35397419875SJosh Stone
354a9cfb877SMathieu Desnoyers #define DEFINE_TRACE_FN(_name, _reg, _unreg, _proto, _args) \
355a9cfb877SMathieu Desnoyers static struct tracepoint_ext __tracepoint_ext_##_name = { \
356a9cfb877SMathieu Desnoyers .regfunc = _reg, \
357a9cfb877SMathieu Desnoyers .unregfunc = _unreg, \
358654ced4aSMathieu Desnoyers .faultable = false, \
359654ced4aSMathieu Desnoyers }; \
360654ced4aSMathieu Desnoyers __DEFINE_TRACE_EXT(_name, &__tracepoint_ext_##_name, PARAMS(_proto), PARAMS(_args));
361654ced4aSMathieu Desnoyers
362654ced4aSMathieu Desnoyers #define DEFINE_TRACE_SYSCALL(_name, _reg, _unreg, _proto, _args) \
363654ced4aSMathieu Desnoyers static struct tracepoint_ext __tracepoint_ext_##_name = { \
364654ced4aSMathieu Desnoyers .regfunc = _reg, \
365654ced4aSMathieu Desnoyers .unregfunc = _unreg, \
366654ced4aSMathieu Desnoyers .faultable = true, \
367a9cfb877SMathieu Desnoyers }; \
368a9cfb877SMathieu Desnoyers __DEFINE_TRACE_EXT(_name, &__tracepoint_ext_##_name, PARAMS(_proto), PARAMS(_args));
369a9cfb877SMathieu Desnoyers
370a9cfb877SMathieu Desnoyers #define DEFINE_TRACE(_name, _proto, _args) \
371a9cfb877SMathieu Desnoyers __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
3727e066fb8SMathieu Desnoyers
3737e066fb8SMathieu Desnoyers #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
374d25e37d8SSteven Rostedt (VMware) EXPORT_SYMBOL_GPL(__tracepoint_##name); \
375de394e75S[email protected] EXPORT_SYMBOL_GPL(__traceiter_##name); \
376d25e37d8SSteven Rostedt (VMware) EXPORT_STATIC_CALL_GPL(tp_func_##name)
3777e066fb8SMathieu Desnoyers #define EXPORT_TRACEPOINT_SYMBOL(name) \
378d25e37d8SSteven Rostedt (VMware) EXPORT_SYMBOL(__tracepoint_##name); \
379de394e75S[email protected] EXPORT_SYMBOL(__traceiter_##name); \
380d25e37d8SSteven Rostedt (VMware) EXPORT_STATIC_CALL(tp_func_##name)
381d25e37d8SSteven Rostedt (VMware)
3827e066fb8SMathieu Desnoyers
383c63b7682STal Shorer #else /* !TRACEPOINTS_ENABLED */
384ef0d4186SMathieu Desnoyers #define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \
38597e1c18eSMathieu Desnoyers static inline void trace_##name(proto) \
38697e1c18eSMathieu Desnoyers { } \
38738516ab5SSteven Rostedt static inline int \
38838516ab5SSteven Rostedt register_trace_##name(void (*probe)(data_proto), \
38938516ab5SSteven Rostedt void *data) \
39097e1c18eSMathieu Desnoyers { \
39197e1c18eSMathieu Desnoyers return -ENOSYS; \
39297e1c18eSMathieu Desnoyers } \
39338516ab5SSteven Rostedt static inline int \
39438516ab5SSteven Rostedt unregister_trace_##name(void (*probe)(data_proto), \
39538516ab5SSteven Rostedt void *data) \
396c420970eSMathieu Desnoyers { \
397c420970eSMathieu Desnoyers return -ENOSYS; \
39853da59aaSMathieu Desnoyers } \
39938516ab5SSteven Rostedt static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
40053da59aaSMathieu Desnoyers { \
4017c65bbc7SSteven Rostedt (Red Hat) } \
4027c65bbc7SSteven Rostedt (Red Hat) static inline bool \
4037c65bbc7SSteven Rostedt (Red Hat) trace_##name##_enabled(void) \
4047c65bbc7SSteven Rostedt (Red Hat) { \
4057c65bbc7SSteven Rostedt (Red Hat) return false; \
406c420970eSMathieu Desnoyers }
40797e1c18eSMathieu Desnoyers
408ef0d4186SMathieu Desnoyers #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
409ef0d4186SMathieu Desnoyers __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto))
410ef0d4186SMathieu Desnoyers
411ef0d4186SMathieu Desnoyers #define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \
412ef0d4186SMathieu Desnoyers __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto))
4130e6caab8SMathieu Desnoyers
414d25e37d8SSteven Rostedt (VMware) #define DEFINE_TRACE_FN(name, reg, unreg, proto, args)
415654ced4aSMathieu Desnoyers #define DEFINE_TRACE_SYSCALL(name, reg, unreg, proto, args)
416d25e37d8SSteven Rostedt (VMware) #define DEFINE_TRACE(name, proto, args)
4177e066fb8SMathieu Desnoyers #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
4187e066fb8SMathieu Desnoyers #define EXPORT_TRACEPOINT_SYMBOL(name)
4197e066fb8SMathieu Desnoyers
420c63b7682STal Shorer #endif /* TRACEPOINTS_ENABLED */
42138516ab5SSteven Rostedt
4223c49b52bSSteven Rostedt #ifdef CONFIG_TRACING
4233c49b52bSSteven Rostedt /**
4243c49b52bSSteven Rostedt * tracepoint_string - register constant persistent string to trace system
4253c49b52bSSteven Rostedt * @str - a constant persistent string that will be referenced in tracepoints
4263c49b52bSSteven Rostedt *
4273c49b52bSSteven Rostedt * If constant strings are being used in tracepoints, it is faster and
4283c49b52bSSteven Rostedt * more efficient to just save the pointer to the string and reference
4293c49b52bSSteven Rostedt * that with a printf "%s" instead of saving the string in the ring buffer
4303c49b52bSSteven Rostedt * and wasting space and time.
4313c49b52bSSteven Rostedt *
4323c49b52bSSteven Rostedt * The problem with the above approach is that userspace tools that read
4333c49b52bSSteven Rostedt * the binary output of the trace buffers do not have access to the string.
4343c49b52bSSteven Rostedt * Instead they just show the address of the string which is not very
4353c49b52bSSteven Rostedt * useful to users.
4363c49b52bSSteven Rostedt *
4373c49b52bSSteven Rostedt * With tracepoint_string(), the string will be registered to the tracing
4383c49b52bSSteven Rostedt * system and exported to userspace via the debugfs/tracing/printk_formats
4393c49b52bSSteven Rostedt * file that maps the string address to the string text. This way userspace
4403c49b52bSSteven Rostedt * tools that read the binary buffers have a way to map the pointers to
4413c49b52bSSteven Rostedt * the ASCII strings they represent.
4423c49b52bSSteven Rostedt *
4433c49b52bSSteven Rostedt * The @str used must be a constant string and persistent as it would not
4443c49b52bSSteven Rostedt * make sense to show a string that no longer exists. But it is still fine
4453c49b52bSSteven Rostedt * to be used with modules, because when modules are unloaded, if they
4463c49b52bSSteven Rostedt * had tracepoints, the ring buffers are cleared too. As long as the string
4473c49b52bSSteven Rostedt * does not change during the life of the module, it is fine to use
4483c49b52bSSteven Rostedt * tracepoint_string() within a module.
4493c49b52bSSteven Rostedt */
4503c49b52bSSteven Rostedt #define tracepoint_string(str) \
4513c49b52bSSteven Rostedt ({ \
4523c49b52bSSteven Rostedt static const char *___tp_str __tracepoint_string = str; \
4533c49b52bSSteven Rostedt ___tp_str; \
4543c49b52bSSteven Rostedt })
45533def849SJoe Perches #define __tracepoint_string __used __section("__tracepoint_str")
4563c49b52bSSteven Rostedt #else
4573c49b52bSSteven Rostedt /*
4583c49b52bSSteven Rostedt * tracepoint_string() is used to save the string address for userspace
4593c49b52bSSteven Rostedt * tracing tools. When tracing isn't configured, there's no need to save
4603c49b52bSSteven Rostedt * anything.
4613c49b52bSSteven Rostedt */
4623c49b52bSSteven Rostedt # define tracepoint_string(str) str
4633c49b52bSSteven Rostedt # define __tracepoint_string
4643c49b52bSSteven Rostedt #endif
4653c49b52bSSteven Rostedt
46638516ab5SSteven Rostedt #define DECLARE_TRACE(name, proto, args) \
467dc17147dSSteven Rostedt (Red Hat) __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
468dc17147dSSteven Rostedt (Red Hat) cpu_online(raw_smp_processor_id()), \
4691746fd44SSteven Rostedt (VMware) PARAMS(void *__data, proto))
470287050d3SSteven Rostedt
471287050d3SSteven Rostedt #define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
472dc17147dSSteven Rostedt (Red Hat) __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
473dc17147dSSteven Rostedt (Red Hat) cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
4741746fd44SSteven Rostedt (VMware) PARAMS(void *__data, proto))
47538516ab5SSteven Rostedt
4760e6caab8SMathieu Desnoyers #define DECLARE_TRACE_SYSCALL(name, proto, args) \
4770e6caab8SMathieu Desnoyers __DECLARE_TRACE_SYSCALL(name, PARAMS(proto), PARAMS(args), \
4780e6caab8SMathieu Desnoyers PARAMS(void *__data, proto))
4790e6caab8SMathieu Desnoyers
4801ed0c597SFrederic Weisbecker #define TRACE_EVENT_FLAGS(event, flag)
4811ed0c597SFrederic Weisbecker
482d5b5f391SPeter Zijlstra #define TRACE_EVENT_PERF_PERM(event, expr...)
483d5b5f391SPeter Zijlstra
484ea20d929SSteven Rostedt #endif /* DECLARE_TRACE */
48597e1c18eSMathieu Desnoyers
486ea20d929SSteven Rostedt #ifndef TRACE_EVENT
487823f9124SSteven Rostedt /*
488823f9124SSteven Rostedt * For use with the TRACE_EVENT macro:
489823f9124SSteven Rostedt *
490823f9124SSteven Rostedt * We define a tracepoint, its arguments, its printk format
4912621bca8SViresh Kumar * and its 'fast binary record' layout.
492823f9124SSteven Rostedt *
493823f9124SSteven Rostedt * Firstly, name your tracepoint via TRACE_EVENT(name : the
494823f9124SSteven Rostedt * 'subsystem_event' notation is fine.
495823f9124SSteven Rostedt *
496823f9124SSteven Rostedt * Think about this whole construct as the
497823f9124SSteven Rostedt * 'trace_sched_switch() function' from now on.
498823f9124SSteven Rostedt *
499823f9124SSteven Rostedt *
500823f9124SSteven Rostedt * TRACE_EVENT(sched_switch,
501823f9124SSteven Rostedt *
502823f9124SSteven Rostedt * *
503823f9124SSteven Rostedt * * A function has a regular function arguments
504823f9124SSteven Rostedt * * prototype, declare it via TP_PROTO():
505823f9124SSteven Rostedt * *
506823f9124SSteven Rostedt *
507823f9124SSteven Rostedt * TP_PROTO(struct rq *rq, struct task_struct *prev,
508823f9124SSteven Rostedt * struct task_struct *next),
509823f9124SSteven Rostedt *
510823f9124SSteven Rostedt * *
511823f9124SSteven Rostedt * * Define the call signature of the 'function'.
512823f9124SSteven Rostedt * * (Design sidenote: we use this instead of a
513823f9124SSteven Rostedt * * TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.)
514823f9124SSteven Rostedt * *
515823f9124SSteven Rostedt *
516823f9124SSteven Rostedt * TP_ARGS(rq, prev, next),
517823f9124SSteven Rostedt *
518823f9124SSteven Rostedt * *
519823f9124SSteven Rostedt * * Fast binary tracing: define the trace record via
520823f9124SSteven Rostedt * * TP_STRUCT__entry(). You can think about it like a
521823f9124SSteven Rostedt * * regular C structure local variable definition.
522823f9124SSteven Rostedt * *
523823f9124SSteven Rostedt * * This is how the trace record is structured and will
524823f9124SSteven Rostedt * * be saved into the ring buffer. These are the fields
525823f9124SSteven Rostedt * * that will be exposed to user-space in
5262455f0e1SRoss Zwisler * * /sys/kernel/tracing/events/<*>/format.
527823f9124SSteven Rostedt * *
528823f9124SSteven Rostedt * * The declared 'local variable' is called '__entry'
529823f9124SSteven Rostedt * *
530c3b1c377SHuang Shijie * * __field(pid_t, prev_pid) is equivalent to a standard declaration:
531823f9124SSteven Rostedt * *
532823f9124SSteven Rostedt * * pid_t prev_pid;
533823f9124SSteven Rostedt * *
534823f9124SSteven Rostedt * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to:
535823f9124SSteven Rostedt * *
536823f9124SSteven Rostedt * * char prev_comm[TASK_COMM_LEN];
537823f9124SSteven Rostedt * *
538823f9124SSteven Rostedt *
539823f9124SSteven Rostedt * TP_STRUCT__entry(
540823f9124SSteven Rostedt * __array( char, prev_comm, TASK_COMM_LEN )
541823f9124SSteven Rostedt * __field( pid_t, prev_pid )
542823f9124SSteven Rostedt * __field( int, prev_prio )
543823f9124SSteven Rostedt * __array( char, next_comm, TASK_COMM_LEN )
544823f9124SSteven Rostedt * __field( pid_t, next_pid )
545823f9124SSteven Rostedt * __field( int, next_prio )
546823f9124SSteven Rostedt * ),
547823f9124SSteven Rostedt *
548823f9124SSteven Rostedt * *
549823f9124SSteven Rostedt * * Assign the entry into the trace record, by embedding
550823f9124SSteven Rostedt * * a full C statement block into TP_fast_assign(). You
551823f9124SSteven Rostedt * * can refer to the trace record as '__entry' -
552823f9124SSteven Rostedt * * otherwise you can put arbitrary C code in here.
553823f9124SSteven Rostedt * *
554823f9124SSteven Rostedt * * Note: this C code will execute every time a trace event
555823f9124SSteven Rostedt * * happens, on an active tracepoint.
556823f9124SSteven Rostedt * *
557823f9124SSteven Rostedt *
558823f9124SSteven Rostedt * TP_fast_assign(
559823f9124SSteven Rostedt * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
560823f9124SSteven Rostedt * __entry->prev_pid = prev->pid;
561823f9124SSteven Rostedt * __entry->prev_prio = prev->prio;
562823f9124SSteven Rostedt * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
563823f9124SSteven Rostedt * __entry->next_pid = next->pid;
564823f9124SSteven Rostedt * __entry->next_prio = next->prio;
565ec6e7c3aSMathieu Desnoyers * ),
566823f9124SSteven Rostedt *
567823f9124SSteven Rostedt * *
568823f9124SSteven Rostedt * * Formatted output of a trace record via TP_printk().
569823f9124SSteven Rostedt * * This is how the tracepoint will appear under ftrace
570823f9124SSteven Rostedt * * plugins that make use of this tracepoint.
571823f9124SSteven Rostedt * *
572823f9124SSteven Rostedt * * (raw-binary tracing wont actually perform this step.)
573823f9124SSteven Rostedt * *
574823f9124SSteven Rostedt *
575823f9124SSteven Rostedt * TP_printk("task %s:%d [%d] ==> %s:%d [%d]",
576823f9124SSteven Rostedt * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
577823f9124SSteven Rostedt * __entry->next_comm, __entry->next_pid, __entry->next_prio),
578823f9124SSteven Rostedt *
579823f9124SSteven Rostedt * );
580823f9124SSteven Rostedt *
581823f9124SSteven Rostedt * This macro construct is thus used for the regular printk format
582823f9124SSteven Rostedt * tracing setup, it is used to construct a function pointer based
583823f9124SSteven Rostedt * tracepoint callback (this is used by programmatic plugins and
584823f9124SSteven Rostedt * can also by used by generic instrumentation like SystemTap), and
585823f9124SSteven Rostedt * it is also used to expose a structured trace record in
5862455f0e1SRoss Zwisler * /sys/kernel/tracing/events/.
58797419875SJosh Stone *
58897419875SJosh Stone * A set of (un)registration functions can be passed to the variant
58997419875SJosh Stone * TRACE_EVENT_FN to perform any (un)registration work.
590823f9124SSteven Rostedt */
591823f9124SSteven Rostedt
592091ad365SIngo Molnar #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
593ff038f5cSSteven Rostedt #define DEFINE_EVENT(template, name, proto, args) \
594ff038f5cSSteven Rostedt DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
595f5abaa1bSSteven Rostedt #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
596f5abaa1bSSteven Rostedt DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
597e5bc9721SSteven Rostedt #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
598e5bc9721SSteven Rostedt DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
599287050d3SSteven Rostedt #define DEFINE_EVENT_CONDITION(template, name, proto, \
600287050d3SSteven Rostedt args, cond) \
601287050d3SSteven Rostedt DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
602287050d3SSteven Rostedt PARAMS(args), PARAMS(cond))
603ff038f5cSSteven Rostedt
60430a8feccSSteven Rostedt #define TRACE_EVENT(name, proto, args, struct, assign, print) \
605da4d0302SSteven Rostedt DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
60697419875SJosh Stone #define TRACE_EVENT_FN(name, proto, args, struct, \
60797419875SJosh Stone assign, print, reg, unreg) \
60897419875SJosh Stone DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
6092701121bSDenis Kirjanov #define TRACE_EVENT_FN_COND(name, proto, args, cond, struct, \
6102701121bSDenis Kirjanov assign, print, reg, unreg) \
6112701121bSDenis Kirjanov DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
6122701121bSDenis Kirjanov PARAMS(args), PARAMS(cond))
613287050d3SSteven Rostedt #define TRACE_EVENT_CONDITION(name, proto, args, cond, \
614287050d3SSteven Rostedt struct, assign, print) \
615287050d3SSteven Rostedt DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
616287050d3SSteven Rostedt PARAMS(args), PARAMS(cond))
6170e6caab8SMathieu Desnoyers #define TRACE_EVENT_SYSCALL(name, proto, args, struct, assign, \
6180e6caab8SMathieu Desnoyers print, reg, unreg) \
6190e6caab8SMathieu Desnoyers DECLARE_TRACE_SYSCALL(name, PARAMS(proto), PARAMS(args))
6207cb2e3eeSSteven Rostedt
6211ed0c597SFrederic Weisbecker #define TRACE_EVENT_FLAGS(event, flag)
6221ed0c597SFrederic Weisbecker
623d5b5f391SPeter Zijlstra #define TRACE_EVENT_PERF_PERM(event, expr...)
624d5b5f391SPeter Zijlstra
62516336345SYafang Shao #define DECLARE_EVENT_NOP(name, proto, args) \
62616336345SYafang Shao static inline void trace_##name(proto) \
62716336345SYafang Shao { } \
62816336345SYafang Shao static inline bool trace_##name##_enabled(void) \
62916336345SYafang Shao { \
63016336345SYafang Shao return false; \
63116336345SYafang Shao }
63216336345SYafang Shao
63316336345SYafang Shao #define TRACE_EVENT_NOP(name, proto, args, struct, assign, print) \
63416336345SYafang Shao DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
63516336345SYafang Shao
63616336345SYafang Shao #define DECLARE_EVENT_CLASS_NOP(name, proto, args, tstruct, assign, print)
63716336345SYafang Shao #define DEFINE_EVENT_NOP(template, name, proto, args) \
63816336345SYafang Shao DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
63916336345SYafang Shao
6407cb2e3eeSSteven Rostedt #endif /* ifdef TRACE_EVENT (see note above) */
641