1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | #ifndef _LINUX_TRACEPOINT_H |
3 | #define _LINUX_TRACEPOINT_H |
4 | |
5 | /* |
6 | * Kernel Tracepoint API. |
7 | * |
8 | * See Documentation/trace/tracepoints.rst. |
9 | * |
10 | * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
11 | * |
12 | * Heavily inspired from the Linux Kernel Markers. |
13 | */ |
14 | |
15 | #include <linux/smp.h> |
16 | #include <linux/srcu.h> |
17 | #include <linux/errno.h> |
18 | #include <linux/types.h> |
19 | #include <linux/cpumask.h> |
20 | #include <linux/rcupdate.h> |
21 | #include <linux/tracepoint-defs.h> |
22 | #include <linux/static_call.h> |
23 | |
24 | struct module; |
25 | struct tracepoint; |
26 | struct notifier_block; |
27 | |
28 | struct trace_eval_map { |
29 | const char *system; |
30 | const char *eval_string; |
31 | unsigned long eval_value; |
32 | }; |
33 | |
34 | #define TRACEPOINT_DEFAULT_PRIO 10 |
35 | |
36 | extern struct srcu_struct tracepoint_srcu; |
37 | |
38 | extern int |
39 | tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); |
40 | extern int |
41 | tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, |
42 | int prio); |
43 | extern int |
44 | tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data, |
45 | int prio); |
46 | extern int |
47 | tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data); |
48 | static inline int |
49 | tracepoint_probe_register_may_exist(struct tracepoint *tp, void *probe, |
50 | void *data) |
51 | { |
52 | return tracepoint_probe_register_prio_may_exist(tp, probe, data, |
53 | TRACEPOINT_DEFAULT_PRIO); |
54 | } |
55 | extern void |
56 | for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), |
57 | void *priv); |
58 | |
59 | #ifdef CONFIG_MODULES |
60 | struct tp_module { |
61 | struct list_head list; |
62 | struct module *mod; |
63 | }; |
64 | |
65 | bool trace_module_has_bad_taint(struct module *mod); |
66 | extern int register_tracepoint_module_notifier(struct notifier_block *nb); |
67 | extern int unregister_tracepoint_module_notifier(struct notifier_block *nb); |
68 | #else |
69 | static inline bool trace_module_has_bad_taint(struct module *mod) |
70 | { |
71 | return false; |
72 | } |
73 | static inline |
74 | int register_tracepoint_module_notifier(struct notifier_block *nb) |
75 | { |
76 | return 0; |
77 | } |
78 | static inline |
79 | int unregister_tracepoint_module_notifier(struct notifier_block *nb) |
80 | { |
81 | return 0; |
82 | } |
83 | #endif /* CONFIG_MODULES */ |
84 | |
85 | /* |
86 | * tracepoint_synchronize_unregister must be called between the last tracepoint |
87 | * probe unregistration and the end of module exit to make sure there is no |
88 | * caller executing a probe when it is freed. |
89 | */ |
90 | #ifdef CONFIG_TRACEPOINTS |
91 | static inline void tracepoint_synchronize_unregister(void) |
92 | { |
93 | synchronize_srcu(ssp: &tracepoint_srcu); |
94 | synchronize_rcu(); |
95 | } |
96 | #else |
97 | static inline void tracepoint_synchronize_unregister(void) |
98 | { } |
99 | #endif |
100 | |
101 | #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS |
102 | extern int syscall_regfunc(void); |
103 | extern void syscall_unregfunc(void); |
104 | #endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */ |
105 | |
106 | #ifndef PARAMS |
107 | #define PARAMS(args...) args |
108 | #endif |
109 | |
110 | #define TRACE_DEFINE_ENUM(x) |
111 | #define TRACE_DEFINE_SIZEOF(x) |
112 | |
113 | #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS |
114 | static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) |
115 | { |
116 | return offset_to_ptr(off: p); |
117 | } |
118 | |
119 | #define __TRACEPOINT_ENTRY(name) \ |
120 | asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \ |
121 | " .balign 4 \n" \ |
122 | " .long __tracepoint_" #name " - . \n" \ |
123 | " .previous \n") |
124 | #else |
125 | static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) |
126 | { |
127 | return *p; |
128 | } |
129 | |
130 | #define __TRACEPOINT_ENTRY(name) \ |
131 | static tracepoint_ptr_t __tracepoint_ptr_##name __used \ |
132 | __section("__tracepoints_ptrs") = &__tracepoint_##name |
133 | #endif |
134 | |
135 | #endif /* _LINUX_TRACEPOINT_H */ |
136 | |
137 | /* |
138 | * Note: we keep the TRACE_EVENT and DECLARE_TRACE outside the include |
139 | * file ifdef protection. |
140 | * This is due to the way trace events work. If a file includes two |
141 | * trace event headers under one "CREATE_TRACE_POINTS" the first include |
142 | * will override the TRACE_EVENT and break the second include. |
143 | */ |
144 | |
145 | #ifndef DECLARE_TRACE |
146 | |
147 | #define TP_PROTO(args...) args |
148 | #define TP_ARGS(args...) args |
149 | #define TP_CONDITION(args...) args |
150 | |
151 | /* |
152 | * Individual subsystem my have a separate configuration to |
153 | * enable their tracepoints. By default, this file will create |
154 | * the tracepoints if CONFIG_TRACEPOINTS is defined. If a subsystem |
155 | * wants to be able to disable its tracepoints from being created |
156 | * it can define NOTRACE before including the tracepoint headers. |
157 | */ |
158 | #if defined(CONFIG_TRACEPOINTS) && !defined(NOTRACE) |
159 | #define TRACEPOINTS_ENABLED |
160 | #endif |
161 | |
162 | #ifdef TRACEPOINTS_ENABLED |
163 | |
164 | #ifdef CONFIG_HAVE_STATIC_CALL |
165 | #define __DO_TRACE_CALL(name, args) \ |
166 | do { \ |
167 | struct tracepoint_func *it_func_ptr; \ |
168 | void *__data; \ |
169 | it_func_ptr = \ |
170 | rcu_dereference_raw((&__tracepoint_##name)->funcs); \ |
171 | if (it_func_ptr) { \ |
172 | __data = (it_func_ptr)->data; \ |
173 | static_call(tp_func_##name)(__data, args); \ |
174 | } \ |
175 | } while (0) |
176 | #else |
177 | #define __DO_TRACE_CALL(name, args) __traceiter_##name(NULL, args) |
178 | #endif /* CONFIG_HAVE_STATIC_CALL */ |
179 | |
180 | /* |
181 | * ARCH_WANTS_NO_INSTR archs are expected to have sanitized entry and idle |
182 | * code that disallow any/all tracing/instrumentation when RCU isn't watching. |
183 | */ |
184 | #ifdef CONFIG_ARCH_WANTS_NO_INSTR |
185 | #define RCUIDLE_COND(rcuidle) (rcuidle) |
186 | #else |
187 | /* srcu can't be used from NMI */ |
188 | #define RCUIDLE_COND(rcuidle) (rcuidle && in_nmi()) |
189 | #endif |
190 | |
191 | /* |
192 | * it_func[0] is never NULL because there is at least one element in the array |
193 | * when the array itself is non NULL. |
194 | */ |
195 | #define __DO_TRACE(name, args, cond, rcuidle) \ |
196 | do { \ |
197 | int __maybe_unused __idx = 0; \ |
198 | \ |
199 | if (!(cond)) \ |
200 | return; \ |
201 | \ |
202 | if (WARN_ON_ONCE(RCUIDLE_COND(rcuidle))) \ |
203 | return; \ |
204 | \ |
205 | /* keep srcu and sched-rcu usage consistent */ \ |
206 | preempt_disable_notrace(); \ |
207 | \ |
208 | /* \ |
209 | * For rcuidle callers, use srcu since sched-rcu \ |
210 | * doesn't work from the idle path. \ |
211 | */ \ |
212 | if (rcuidle) { \ |
213 | __idx = srcu_read_lock_notrace(&tracepoint_srcu);\ |
214 | ct_irq_enter_irqson(); \ |
215 | } \ |
216 | \ |
217 | __DO_TRACE_CALL(name, TP_ARGS(args)); \ |
218 | \ |
219 | if (rcuidle) { \ |
220 | ct_irq_exit_irqson(); \ |
221 | srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\ |
222 | } \ |
223 | \ |
224 | preempt_enable_notrace(); \ |
225 | } while (0) |
226 | |
227 | #ifndef MODULE |
228 | #define __DECLARE_TRACE_RCU(name, proto, args, cond) \ |
229 | static inline void trace_##name##_rcuidle(proto) \ |
230 | { \ |
231 | if (static_key_false(&__tracepoint_##name.key)) \ |
232 | __DO_TRACE(name, \ |
233 | TP_ARGS(args), \ |
234 | TP_CONDITION(cond), 1); \ |
235 | } |
236 | #else |
237 | #define __DECLARE_TRACE_RCU(name, proto, args, cond) |
238 | #endif |
239 | |
240 | /* |
241 | * Make sure the alignment of the structure in the __tracepoints section will |
242 | * not add unwanted padding between the beginning of the section and the |
243 | * structure. Force alignment to the same alignment as the section start. |
244 | * |
245 | * When lockdep is enabled, we make sure to always test if RCU is |
246 | * "watching" regardless if the tracepoint is enabled or not. Tracepoints |
247 | * require RCU to be active, and it should always warn at the tracepoint |
248 | * site if it is not watching, as it will need to be active when the |
249 | * tracepoint is enabled. |
250 | */ |
251 | #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ |
252 | extern int __traceiter_##name(data_proto); \ |
253 | DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \ |
254 | extern struct tracepoint __tracepoint_##name; \ |
255 | static inline void trace_##name(proto) \ |
256 | { \ |
257 | if (static_key_false(&__tracepoint_##name.key)) \ |
258 | __DO_TRACE(name, \ |
259 | TP_ARGS(args), \ |
260 | TP_CONDITION(cond), 0); \ |
261 | if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ |
262 | WARN_ON_ONCE(!rcu_is_watching()); \ |
263 | } \ |
264 | } \ |
265 | __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \ |
266 | PARAMS(cond)) \ |
267 | static inline int \ |
268 | register_trace_##name(void (*probe)(data_proto), void *data) \ |
269 | { \ |
270 | return tracepoint_probe_register(&__tracepoint_##name, \ |
271 | (void *)probe, data); \ |
272 | } \ |
273 | static inline int \ |
274 | register_trace_prio_##name(void (*probe)(data_proto), void *data,\ |
275 | int prio) \ |
276 | { \ |
277 | return tracepoint_probe_register_prio(&__tracepoint_##name, \ |
278 | (void *)probe, data, prio); \ |
279 | } \ |
280 | static inline int \ |
281 | unregister_trace_##name(void (*probe)(data_proto), void *data) \ |
282 | { \ |
283 | return tracepoint_probe_unregister(&__tracepoint_##name,\ |
284 | (void *)probe, data); \ |
285 | } \ |
286 | static inline void \ |
287 | check_trace_callback_type_##name(void (*cb)(data_proto)) \ |
288 | { \ |
289 | } \ |
290 | static inline bool \ |
291 | trace_##name##_enabled(void) \ |
292 | { \ |
293 | return static_key_false(&__tracepoint_##name.key); \ |
294 | } |
295 | |
296 | /* |
297 | * We have no guarantee that gcc and the linker won't up-align the tracepoint |
298 | * structures, so we create an array of pointers that will be used for iteration |
299 | * on the tracepoints. |
300 | */ |
301 | #define DEFINE_TRACE_FN(_name, _reg, _unreg, proto, args) \ |
302 | static const char __tpstrtab_##_name[] \ |
303 | __section("__tracepoints_strings") = #_name; \ |
304 | extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \ |
305 | int __traceiter_##_name(void *__data, proto); \ |
306 | void __probestub_##_name(void *__data, proto); \ |
307 | struct tracepoint __tracepoint_##_name __used \ |
308 | __section("__tracepoints") = { \ |
309 | .name = __tpstrtab_##_name, \ |
310 | .key = STATIC_KEY_INIT_FALSE, \ |
311 | .static_call_key = &STATIC_CALL_KEY(tp_func_##_name), \ |
312 | .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \ |
313 | .iterator = &__traceiter_##_name, \ |
314 | .probestub = &__probestub_##_name, \ |
315 | .regfunc = _reg, \ |
316 | .unregfunc = _unreg, \ |
317 | .funcs = NULL }; \ |
318 | __TRACEPOINT_ENTRY(_name); \ |
319 | int __traceiter_##_name(void *__data, proto) \ |
320 | { \ |
321 | struct tracepoint_func *it_func_ptr; \ |
322 | void *it_func; \ |
323 | \ |
324 | it_func_ptr = \ |
325 | rcu_dereference_raw((&__tracepoint_##_name)->funcs); \ |
326 | if (it_func_ptr) { \ |
327 | do { \ |
328 | it_func = READ_ONCE((it_func_ptr)->func); \ |
329 | __data = (it_func_ptr)->data; \ |
330 | ((void(*)(void *, proto))(it_func))(__data, args); \ |
331 | } while ((++it_func_ptr)->func); \ |
332 | } \ |
333 | return 0; \ |
334 | } \ |
335 | void __probestub_##_name(void *__data, proto) \ |
336 | { \ |
337 | } \ |
338 | DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); |
339 | |
340 | #define DEFINE_TRACE(name, proto, args) \ |
341 | DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args)); |
342 | |
343 | #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ |
344 | EXPORT_SYMBOL_GPL(__tracepoint_##name); \ |
345 | EXPORT_SYMBOL_GPL(__traceiter_##name); \ |
346 | EXPORT_STATIC_CALL_GPL(tp_func_##name) |
347 | #define EXPORT_TRACEPOINT_SYMBOL(name) \ |
348 | EXPORT_SYMBOL(__tracepoint_##name); \ |
349 | EXPORT_SYMBOL(__traceiter_##name); \ |
350 | EXPORT_STATIC_CALL(tp_func_##name) |
351 | |
352 | |
353 | #else /* !TRACEPOINTS_ENABLED */ |
354 | #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ |
355 | static inline void trace_##name(proto) \ |
356 | { } \ |
357 | static inline void trace_##name##_rcuidle(proto) \ |
358 | { } \ |
359 | static inline int \ |
360 | register_trace_##name(void (*probe)(data_proto), \ |
361 | void *data) \ |
362 | { \ |
363 | return -ENOSYS; \ |
364 | } \ |
365 | static inline int \ |
366 | unregister_trace_##name(void (*probe)(data_proto), \ |
367 | void *data) \ |
368 | { \ |
369 | return -ENOSYS; \ |
370 | } \ |
371 | static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \ |
372 | { \ |
373 | } \ |
374 | static inline bool \ |
375 | trace_##name##_enabled(void) \ |
376 | { \ |
377 | return false; \ |
378 | } |
379 | |
380 | #define DEFINE_TRACE_FN(name, reg, unreg, proto, args) |
381 | #define DEFINE_TRACE(name, proto, args) |
382 | #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) |
383 | #define EXPORT_TRACEPOINT_SYMBOL(name) |
384 | |
385 | #endif /* TRACEPOINTS_ENABLED */ |
386 | |
387 | #ifdef CONFIG_TRACING |
388 | /** |
389 | * tracepoint_string - register constant persistent string to trace system |
390 | * @str - a constant persistent string that will be referenced in tracepoints |
391 | * |
392 | * If constant strings are being used in tracepoints, it is faster and |
393 | * more efficient to just save the pointer to the string and reference |
394 | * that with a printf "%s" instead of saving the string in the ring buffer |
395 | * and wasting space and time. |
396 | * |
397 | * The problem with the above approach is that userspace tools that read |
398 | * the binary output of the trace buffers do not have access to the string. |
399 | * Instead they just show the address of the string which is not very |
400 | * useful to users. |
401 | * |
402 | * With tracepoint_string(), the string will be registered to the tracing |
403 | * system and exported to userspace via the debugfs/tracing/printk_formats |
404 | * file that maps the string address to the string text. This way userspace |
405 | * tools that read the binary buffers have a way to map the pointers to |
406 | * the ASCII strings they represent. |
407 | * |
408 | * The @str used must be a constant string and persistent as it would not |
409 | * make sense to show a string that no longer exists. But it is still fine |
410 | * to be used with modules, because when modules are unloaded, if they |
411 | * had tracepoints, the ring buffers are cleared too. As long as the string |
412 | * does not change during the life of the module, it is fine to use |
413 | * tracepoint_string() within a module. |
414 | */ |
415 | #define tracepoint_string(str) \ |
416 | ({ \ |
417 | static const char *___tp_str __tracepoint_string = str; \ |
418 | ___tp_str; \ |
419 | }) |
420 | #define __tracepoint_string __used __section("__tracepoint_str") |
421 | #else |
422 | /* |
423 | * tracepoint_string() is used to save the string address for userspace |
424 | * tracing tools. When tracing isn't configured, there's no need to save |
425 | * anything. |
426 | */ |
427 | # define tracepoint_string(str) str |
428 | # define __tracepoint_string |
429 | #endif |
430 | |
431 | #define DECLARE_TRACE(name, proto, args) \ |
432 | __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ |
433 | cpu_online(raw_smp_processor_id()), \ |
434 | PARAMS(void *__data, proto)) |
435 | |
436 | #define DECLARE_TRACE_CONDITION(name, proto, args, cond) \ |
437 | __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ |
438 | cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \ |
439 | PARAMS(void *__data, proto)) |
440 | |
441 | #define TRACE_EVENT_FLAGS(event, flag) |
442 | |
443 | #define TRACE_EVENT_PERF_PERM(event, expr...) |
444 | |
445 | #endif /* DECLARE_TRACE */ |
446 | |
447 | #ifndef TRACE_EVENT |
448 | /* |
449 | * For use with the TRACE_EVENT macro: |
450 | * |
451 | * We define a tracepoint, its arguments, its printk format |
452 | * and its 'fast binary record' layout. |
453 | * |
454 | * Firstly, name your tracepoint via TRACE_EVENT(name : the |
455 | * 'subsystem_event' notation is fine. |
456 | * |
457 | * Think about this whole construct as the |
458 | * 'trace_sched_switch() function' from now on. |
459 | * |
460 | * |
461 | * TRACE_EVENT(sched_switch, |
462 | * |
463 | * * |
464 | * * A function has a regular function arguments |
465 | * * prototype, declare it via TP_PROTO(): |
466 | * * |
467 | * |
468 | * TP_PROTO(struct rq *rq, struct task_struct *prev, |
469 | * struct task_struct *next), |
470 | * |
471 | * * |
472 | * * Define the call signature of the 'function'. |
473 | * * (Design sidenote: we use this instead of a |
474 | * * TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.) |
475 | * * |
476 | * |
477 | * TP_ARGS(rq, prev, next), |
478 | * |
479 | * * |
480 | * * Fast binary tracing: define the trace record via |
481 | * * TP_STRUCT__entry(). You can think about it like a |
482 | * * regular C structure local variable definition. |
483 | * * |
484 | * * This is how the trace record is structured and will |
485 | * * be saved into the ring buffer. These are the fields |
486 | * * that will be exposed to user-space in |
487 | * * /sys/kernel/tracing/events/<*>/format. |
488 | * * |
489 | * * The declared 'local variable' is called '__entry' |
490 | * * |
491 | * * __field(pid_t, prev_pid) is equivalent to a standard declaration: |
492 | * * |
493 | * * pid_t prev_pid; |
494 | * * |
495 | * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to: |
496 | * * |
497 | * * char prev_comm[TASK_COMM_LEN]; |
498 | * * |
499 | * |
500 | * TP_STRUCT__entry( |
501 | * __array( char, prev_comm, TASK_COMM_LEN ) |
502 | * __field( pid_t, prev_pid ) |
503 | * __field( int, prev_prio ) |
504 | * __array( char, next_comm, TASK_COMM_LEN ) |
505 | * __field( pid_t, next_pid ) |
506 | * __field( int, next_prio ) |
507 | * ), |
508 | * |
509 | * * |
510 | * * Assign the entry into the trace record, by embedding |
511 | * * a full C statement block into TP_fast_assign(). You |
512 | * * can refer to the trace record as '__entry' - |
513 | * * otherwise you can put arbitrary C code in here. |
514 | * * |
515 | * * Note: this C code will execute every time a trace event |
516 | * * happens, on an active tracepoint. |
517 | * * |
518 | * |
519 | * TP_fast_assign( |
520 | * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); |
521 | * __entry->prev_pid = prev->pid; |
522 | * __entry->prev_prio = prev->prio; |
523 | * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); |
524 | * __entry->next_pid = next->pid; |
525 | * __entry->next_prio = next->prio; |
526 | * ), |
527 | * |
528 | * * |
529 | * * Formatted output of a trace record via TP_printk(). |
530 | * * This is how the tracepoint will appear under ftrace |
531 | * * plugins that make use of this tracepoint. |
532 | * * |
533 | * * (raw-binary tracing wont actually perform this step.) |
534 | * * |
535 | * |
536 | * TP_printk("task %s:%d [%d] ==> %s:%d [%d]", |
537 | * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, |
538 | * __entry->next_comm, __entry->next_pid, __entry->next_prio), |
539 | * |
540 | * ); |
541 | * |
542 | * This macro construct is thus used for the regular printk format |
543 | * tracing setup, it is used to construct a function pointer based |
544 | * tracepoint callback (this is used by programmatic plugins and |
545 | * can also by used by generic instrumentation like SystemTap), and |
546 | * it is also used to expose a structured trace record in |
547 | * /sys/kernel/tracing/events/. |
548 | * |
549 | * A set of (un)registration functions can be passed to the variant |
550 | * TRACE_EVENT_FN to perform any (un)registration work. |
551 | */ |
552 | |
553 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) |
554 | #define DEFINE_EVENT(template, name, proto, args) \ |
555 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
556 | #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\ |
557 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
558 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
559 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
560 | #define DEFINE_EVENT_CONDITION(template, name, proto, \ |
561 | args, cond) \ |
562 | DECLARE_TRACE_CONDITION(name, PARAMS(proto), \ |
563 | PARAMS(args), PARAMS(cond)) |
564 | |
565 | #define TRACE_EVENT(name, proto, args, struct, assign, print) \ |
566 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
567 | #define TRACE_EVENT_FN(name, proto, args, struct, \ |
568 | assign, print, reg, unreg) \ |
569 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
570 | #define TRACE_EVENT_FN_COND(name, proto, args, cond, struct, \ |
571 | assign, print, reg, unreg) \ |
572 | DECLARE_TRACE_CONDITION(name, PARAMS(proto), \ |
573 | PARAMS(args), PARAMS(cond)) |
574 | #define TRACE_EVENT_CONDITION(name, proto, args, cond, \ |
575 | struct, assign, print) \ |
576 | DECLARE_TRACE_CONDITION(name, PARAMS(proto), \ |
577 | PARAMS(args), PARAMS(cond)) |
578 | |
579 | #define TRACE_EVENT_FLAGS(event, flag) |
580 | |
581 | #define TRACE_EVENT_PERF_PERM(event, expr...) |
582 | |
583 | #define DECLARE_EVENT_NOP(name, proto, args) \ |
584 | static inline void trace_##name(proto) \ |
585 | { } \ |
586 | static inline bool trace_##name##_enabled(void) \ |
587 | { \ |
588 | return false; \ |
589 | } |
590 | |
591 | #define TRACE_EVENT_NOP(name, proto, args, struct, assign, print) \ |
592 | DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args)) |
593 | |
594 | #define DECLARE_EVENT_CLASS_NOP(name, proto, args, tstruct, assign, print) |
595 | #define DEFINE_EVENT_NOP(template, name, proto, args) \ |
596 | DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args)) |
597 | |
598 | #endif /* ifdef TRACE_EVENT (see note above) */ |
599 | |