1
2#ifndef _LINUX_TRACEPOINT_H
3#define _LINUX_TRACEPOINT_H
4
5
6
7
8
9
10
11
12
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
24struct module;
25struct tracepoint;
26struct notifier_block;
27
28struct 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
36extern struct srcu_struct tracepoint_srcu;
37
38extern int
39tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
40extern int
41tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data,
42 int prio);
43extern int
44tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data,
45 int prio);
46extern int
47tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);
48static inline int
49tracepoint_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}
55extern void
56for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv),
57 void *priv);
58
59#ifdef CONFIG_MODULES
60struct tp_module {
61 struct list_head list;
62 struct module *mod;
63};
64
65bool trace_module_has_bad_taint(struct module *mod);
66extern int register_tracepoint_module_notifier(struct notifier_block *nb);
67extern int unregister_tracepoint_module_notifier(struct notifier_block *nb);
68#else
69static inline bool trace_module_has_bad_taint(struct module *mod)
70{
71 return false;
72}
73static inline
74int register_tracepoint_module_notifier(struct notifier_block *nb)
75{
76 return 0;
77}
78static inline
79int unregister_tracepoint_module_notifier(struct notifier_block *nb)
80{
81 return 0;
82}
83#endif
84
85
86
87
88
89
90#ifdef CONFIG_TRACEPOINTS
91static inline void tracepoint_synchronize_unregister(void)
92{
93 synchronize_srcu(&tracepoint_srcu);
94 synchronize_rcu();
95}
96#else
97static inline void tracepoint_synchronize_unregister(void)
98{ }
99#endif
100
101#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
102extern int syscall_regfunc(void);
103extern void syscall_unregfunc(void);
104#endif
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
114static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
115{
116 return offset_to_ptr(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
125static 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
136
137
138
139
140
141
142
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
153
154
155
156
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
179
180
181
182
183
184#define __DO_TRACE(name, args, cond, rcuidle) \
185 do { \
186 int __maybe_unused __idx = 0; \
187 \
188 if (!(cond)) \
189 return; \
190 \
191 \
192 WARN_ON_ONCE(rcuidle && in_nmi()); \
193 \
194 \
195 preempt_disable_notrace(); \
196 \
197
198
199
200 \
201 if (rcuidle) { \
202 __idx = srcu_read_lock_notrace(&tracepoint_srcu);\
203 rcu_irq_enter_irqson(); \
204 } \
205 \
206 __DO_TRACE_CALL(name, TP_ARGS(args)); \
207 \
208 if (rcuidle) { \
209 rcu_irq_exit_irqson(); \
210 srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\
211 } \
212 \
213 preempt_enable_notrace(); \
214 } while (0)
215
216#ifndef MODULE
217#define __DECLARE_TRACE_RCU(name, proto, args, cond) \
218 static inline void trace_##name##_rcuidle(proto) \
219 { \
220 if (static_key_false(&__tracepoint_##name.key)) \
221 __DO_TRACE(name, \
222 TP_ARGS(args), \
223 TP_CONDITION(cond), 1); \
224 }
225#else
226#define __DECLARE_TRACE_RCU(name, proto, args, cond)
227#endif
228
229
230
231
232
233
234
235
236
237
238
239
240
241#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
242 extern int __traceiter_##name(data_proto); \
243 DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
244 extern struct tracepoint __tracepoint_##name; \
245 static inline void trace_##name(proto) \
246 { \
247 if (static_key_false(&__tracepoint_##name.key)) \
248 __DO_TRACE(name, \
249 TP_ARGS(args), \
250 TP_CONDITION(cond), 0); \
251 if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
252 rcu_read_lock_sched_notrace(); \
253 rcu_dereference_sched(__tracepoint_##name.funcs);\
254 rcu_read_unlock_sched_notrace(); \
255 } \
256 } \
257 __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
258 PARAMS(cond)) \
259 static inline int \
260 register_trace_##name(void (*probe)(data_proto), void *data) \
261 { \
262 return tracepoint_probe_register(&__tracepoint_##name, \
263 (void *)probe, data); \
264 } \
265 static inline int \
266 register_trace_prio_##name(void (*probe)(data_proto), void *data,\
267 int prio) \
268 { \
269 return tracepoint_probe_register_prio(&__tracepoint_##name, \
270 (void *)probe, data, prio); \
271 } \
272 static inline int \
273 unregister_trace_##name(void (*probe)(data_proto), void *data) \
274 { \
275 return tracepoint_probe_unregister(&__tracepoint_##name,\
276 (void *)probe, data); \
277 } \
278 static inline void \
279 check_trace_callback_type_##name(void (*cb)(data_proto)) \
280 { \
281 } \
282 static inline bool \
283 trace_##name##_enabled(void) \
284 { \
285 return static_key_false(&__tracepoint_##name.key); \
286 }
287
288
289
290
291
292
293#define DEFINE_TRACE_FN(_name, _reg, _unreg, proto, args) \
294 static const char __tpstrtab_##_name[] \
295 __section("__tracepoints_strings") = #_name; \
296 extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \
297 int __traceiter_##_name(void *__data, proto); \
298 struct tracepoint __tracepoint_##_name __used \
299 __section("__tracepoints") = { \
300 .name = __tpstrtab_##_name, \
301 .key = STATIC_KEY_INIT_FALSE, \
302 .static_call_key = &STATIC_CALL_KEY(tp_func_##_name), \
303 .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
304 .iterator = &__traceiter_##_name, \
305 .regfunc = _reg, \
306 .unregfunc = _unreg, \
307 .funcs = NULL }; \
308 __TRACEPOINT_ENTRY(_name); \
309 int __traceiter_##_name(void *__data, proto) \
310 { \
311 struct tracepoint_func *it_func_ptr; \
312 void *it_func; \
313 \
314 it_func_ptr = \
315 rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
316 if (it_func_ptr) { \
317 do { \
318 it_func = READ_ONCE((it_func_ptr)->func); \
319 __data = (it_func_ptr)->data; \
320 ((void(*)(void *, proto))(it_func))(__data, args); \
321 } while ((++it_func_ptr)->func); \
322 } \
323 return 0; \
324 } \
325 DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
326
327#define DEFINE_TRACE(name, proto, args) \
328 DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args));
329
330#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
331 EXPORT_SYMBOL_GPL(__tracepoint_##name); \
332 EXPORT_SYMBOL_GPL(__traceiter_##name); \
333 EXPORT_STATIC_CALL_GPL(tp_func_##name)
334#define EXPORT_TRACEPOINT_SYMBOL(name) \
335 EXPORT_SYMBOL(__tracepoint_##name); \
336 EXPORT_SYMBOL(__traceiter_##name); \
337 EXPORT_STATIC_CALL(tp_func_##name)
338
339
340#else
341#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
342 static inline void trace_##name(proto) \
343 { } \
344 static inline void trace_##name##_rcuidle(proto) \
345 { } \
346 static inline int \
347 register_trace_##name(void (*probe)(data_proto), \
348 void *data) \
349 { \
350 return -ENOSYS; \
351 } \
352 static inline int \
353 unregister_trace_##name(void (*probe)(data_proto), \
354 void *data) \
355 { \
356 return -ENOSYS; \
357 } \
358 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
359 { \
360 } \
361 static inline bool \
362 trace_##name##_enabled(void) \
363 { \
364 return false; \
365 }
366
367#define DEFINE_TRACE_FN(name, reg, unreg, proto, args)
368#define DEFINE_TRACE(name, proto, args)
369#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
370#define EXPORT_TRACEPOINT_SYMBOL(name)
371
372#endif
373
374#ifdef CONFIG_TRACING
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402#define tracepoint_string(str) \
403 ({ \
404 static const char *___tp_str __tracepoint_string = str; \
405 ___tp_str; \
406 })
407#define __tracepoint_string __used __section("__tracepoint_str")
408#else
409
410
411
412
413
414# define tracepoint_string(str) str
415# define __tracepoint_string
416#endif
417
418#define DECLARE_TRACE(name, proto, args) \
419 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
420 cpu_online(raw_smp_processor_id()), \
421 PARAMS(void *__data, proto))
422
423#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
424 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
425 cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
426 PARAMS(void *__data, proto))
427
428#define TRACE_EVENT_FLAGS(event, flag)
429
430#define TRACE_EVENT_PERF_PERM(event, expr...)
431
432#endif
433
434#ifndef TRACE_EVENT
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
541#define DEFINE_EVENT(template, name, proto, args) \
542 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
543#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
544 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
545#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
546 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
547#define DEFINE_EVENT_CONDITION(template, name, proto, \
548 args, cond) \
549 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
550 PARAMS(args), PARAMS(cond))
551
552#define TRACE_EVENT(name, proto, args, struct, assign, print) \
553 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
554#define TRACE_EVENT_FN(name, proto, args, struct, \
555 assign, print, reg, unreg) \
556 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
557#define TRACE_EVENT_FN_COND(name, proto, args, cond, struct, \
558 assign, print, reg, unreg) \
559 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
560 PARAMS(args), PARAMS(cond))
561#define TRACE_EVENT_CONDITION(name, proto, args, cond, \
562 struct, assign, print) \
563 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
564 PARAMS(args), PARAMS(cond))
565
566#define TRACE_EVENT_FLAGS(event, flag)
567
568#define TRACE_EVENT_PERF_PERM(event, expr...)
569
570#define DECLARE_EVENT_NOP(name, proto, args) \
571 static inline void trace_##name(proto) \
572 { } \
573 static inline bool trace_##name##_enabled(void) \
574 { \
575 return false; \
576 }
577
578#define TRACE_EVENT_NOP(name, proto, args, struct, assign, print) \
579 DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
580
581#define DECLARE_EVENT_CLASS_NOP(name, proto, args, tstruct, assign, print)
582#define DEFINE_EVENT_NOP(template, name, proto, args) \
583 DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
584
585#endif
586