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_unregister(struct tracepoint *tp, void *probe, void *data);
45extern void
46for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv),
47 void *priv);
48
49#ifdef CONFIG_MODULES
50struct tp_module {
51 struct list_head list;
52 struct module *mod;
53};
54
55bool trace_module_has_bad_taint(struct module *mod);
56extern int register_tracepoint_module_notifier(struct notifier_block *nb);
57extern int unregister_tracepoint_module_notifier(struct notifier_block *nb);
58#else
59static inline bool trace_module_has_bad_taint(struct module *mod)
60{
61 return false;
62}
63static inline
64int register_tracepoint_module_notifier(struct notifier_block *nb)
65{
66 return 0;
67}
68static inline
69int unregister_tracepoint_module_notifier(struct notifier_block *nb)
70{
71 return 0;
72}
73#endif
74
75
76
77
78
79
80#ifdef CONFIG_TRACEPOINTS
81static inline void tracepoint_synchronize_unregister(void)
82{
83 synchronize_srcu(&tracepoint_srcu);
84 synchronize_rcu();
85}
86#else
87static inline void tracepoint_synchronize_unregister(void)
88{ }
89#endif
90
91#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
92extern int syscall_regfunc(void);
93extern void syscall_unregfunc(void);
94#endif
95
96#ifndef PARAMS
97#define PARAMS(args...) args
98#endif
99
100#define TRACE_DEFINE_ENUM(x)
101#define TRACE_DEFINE_SIZEOF(x)
102
103#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
104static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
105{
106 return offset_to_ptr(p);
107}
108
109#define __TRACEPOINT_ENTRY(name) \
110 asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \
111 " .balign 4 \n" \
112 " .long __tracepoint_" #name " - . \n" \
113 " .previous \n")
114#else
115static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
116{
117 return *p;
118}
119
120#define __TRACEPOINT_ENTRY(name) \
121 static tracepoint_ptr_t __tracepoint_ptr_##name __used \
122 __section("__tracepoints_ptrs") = &__tracepoint_##name
123#endif
124
125#endif
126
127
128
129
130
131
132
133
134
135#ifndef DECLARE_TRACE
136
137#define TP_PROTO(args...) args
138#define TP_ARGS(args...) args
139#define TP_CONDITION(args...) args
140
141
142
143
144
145
146
147
148#if defined(CONFIG_TRACEPOINTS) && !defined(NOTRACE)
149#define TRACEPOINTS_ENABLED
150#endif
151
152#ifdef TRACEPOINTS_ENABLED
153
154#ifdef CONFIG_HAVE_STATIC_CALL
155#define __DO_TRACE_CALL(name) static_call(tp_func_##name)
156#else
157#define __DO_TRACE_CALL(name) __traceiter_##name
158#endif
159
160
161
162
163
164
165
166
167
168
169#define __DO_TRACE(name, proto, args, cond, rcuidle) \
170 do { \
171 struct tracepoint_func *it_func_ptr; \
172 int __maybe_unused __idx = 0; \
173 void *__data; \
174 \
175 if (!(cond)) \
176 return; \
177 \
178 \
179 WARN_ON_ONCE(rcuidle && in_nmi()); \
180 \
181 \
182 preempt_disable_notrace(); \
183 \
184
185
186
187 \
188 if (rcuidle) { \
189 __idx = srcu_read_lock_notrace(&tracepoint_srcu);\
190 rcu_irq_enter_irqson(); \
191 } \
192 \
193 it_func_ptr = \
194 rcu_dereference_raw((&__tracepoint_##name)->funcs); \
195 if (it_func_ptr) { \
196 __data = (it_func_ptr)->data; \
197 __DO_TRACE_CALL(name)(args); \
198 } \
199 \
200 if (rcuidle) { \
201 rcu_irq_exit_irqson(); \
202 srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\
203 } \
204 \
205 preempt_enable_notrace(); \
206 } while (0)
207
208#ifndef MODULE
209#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) \
210 static inline void trace_##name##_rcuidle(proto) \
211 { \
212 if (static_key_false(&__tracepoint_##name.key)) \
213 __DO_TRACE(name, \
214 TP_PROTO(data_proto), \
215 TP_ARGS(data_args), \
216 TP_CONDITION(cond), 1); \
217 }
218#else
219#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)
220#endif
221
222
223
224
225
226
227
228
229
230
231
232
233
234#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
235 extern int __traceiter_##name(data_proto); \
236 DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
237 extern struct tracepoint __tracepoint_##name; \
238 static inline void trace_##name(proto) \
239 { \
240 if (static_key_false(&__tracepoint_##name.key)) \
241 __DO_TRACE(name, \
242 TP_PROTO(data_proto), \
243 TP_ARGS(data_args), \
244 TP_CONDITION(cond), 0); \
245 if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
246 rcu_read_lock_sched_notrace(); \
247 rcu_dereference_sched(__tracepoint_##name.funcs);\
248 rcu_read_unlock_sched_notrace(); \
249 } \
250 } \
251 __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
252 PARAMS(cond), PARAMS(data_proto), PARAMS(data_args)) \
253 static inline int \
254 register_trace_##name(void (*probe)(data_proto), void *data) \
255 { \
256 return tracepoint_probe_register(&__tracepoint_##name, \
257 (void *)probe, data); \
258 } \
259 static inline int \
260 register_trace_prio_##name(void (*probe)(data_proto), void *data,\
261 int prio) \
262 { \
263 return tracepoint_probe_register_prio(&__tracepoint_##name, \
264 (void *)probe, data, prio); \
265 } \
266 static inline int \
267 unregister_trace_##name(void (*probe)(data_proto), void *data) \
268 { \
269 return tracepoint_probe_unregister(&__tracepoint_##name,\
270 (void *)probe, data); \
271 } \
272 static inline void \
273 check_trace_callback_type_##name(void (*cb)(data_proto)) \
274 { \
275 } \
276 static inline bool \
277 trace_##name##_enabled(void) \
278 { \
279 return static_key_false(&__tracepoint_##name.key); \
280 }
281
282
283
284
285
286
287#define DEFINE_TRACE_FN(_name, _reg, _unreg, proto, args) \
288 static const char __tpstrtab_##_name[] \
289 __section("__tracepoints_strings") = #_name; \
290 extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \
291 int __traceiter_##_name(void *__data, proto); \
292 struct tracepoint __tracepoint_##_name __used \
293 __section("__tracepoints") = { \
294 .name = __tpstrtab_##_name, \
295 .key = STATIC_KEY_INIT_FALSE, \
296 .static_call_key = &STATIC_CALL_KEY(tp_func_##_name), \
297 .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
298 .iterator = &__traceiter_##_name, \
299 .regfunc = _reg, \
300 .unregfunc = _unreg, \
301 .funcs = NULL }; \
302 __TRACEPOINT_ENTRY(_name); \
303 int __traceiter_##_name(void *__data, proto) \
304 { \
305 struct tracepoint_func *it_func_ptr; \
306 void *it_func; \
307 \
308 it_func_ptr = \
309 rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
310 do { \
311 it_func = (it_func_ptr)->func; \
312 __data = (it_func_ptr)->data; \
313 ((void(*)(void *, proto))(it_func))(__data, args); \
314 } while ((++it_func_ptr)->func); \
315 return 0; \
316 } \
317 DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
318
319#define DEFINE_TRACE(name, proto, args) \
320 DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args));
321
322#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
323 EXPORT_SYMBOL_GPL(__tracepoint_##name); \
324 EXPORT_SYMBOL_GPL(__traceiter_##name); \
325 EXPORT_STATIC_CALL_GPL(tp_func_##name)
326#define EXPORT_TRACEPOINT_SYMBOL(name) \
327 EXPORT_SYMBOL(__tracepoint_##name); \
328 EXPORT_SYMBOL(__traceiter_##name); \
329 EXPORT_STATIC_CALL(tp_func_##name)
330
331
332#else
333#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
334 static inline void trace_##name(proto) \
335 { } \
336 static inline void trace_##name##_rcuidle(proto) \
337 { } \
338 static inline int \
339 register_trace_##name(void (*probe)(data_proto), \
340 void *data) \
341 { \
342 return -ENOSYS; \
343 } \
344 static inline int \
345 unregister_trace_##name(void (*probe)(data_proto), \
346 void *data) \
347 { \
348 return -ENOSYS; \
349 } \
350 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
351 { \
352 } \
353 static inline bool \
354 trace_##name##_enabled(void) \
355 { \
356 return false; \
357 }
358
359#define DEFINE_TRACE_FN(name, reg, unreg, proto, args)
360#define DEFINE_TRACE(name, proto, args)
361#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
362#define EXPORT_TRACEPOINT_SYMBOL(name)
363
364#endif
365
366#ifdef CONFIG_TRACING
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394#define tracepoint_string(str) \
395 ({ \
396 static const char *___tp_str __tracepoint_string = str; \
397 ___tp_str; \
398 })
399#define __tracepoint_string __used __section("__tracepoint_str")
400#else
401
402
403
404
405
406# define tracepoint_string(str) str
407# define __tracepoint_string
408#endif
409
410#define DECLARE_TRACE(name, proto, args) \
411 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
412 cpu_online(raw_smp_processor_id()), \
413 PARAMS(void *__data, proto), \
414 PARAMS(__data, args))
415
416#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
417 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
418 cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
419 PARAMS(void *__data, proto), \
420 PARAMS(__data, args))
421
422#define TRACE_EVENT_FLAGS(event, flag)
423
424#define TRACE_EVENT_PERF_PERM(event, expr...)
425
426#endif
427
428#ifndef TRACE_EVENT
429
430
431
432
433
434
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#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
535#define DEFINE_EVENT(template, name, proto, args) \
536 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
537#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
538 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
539#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
540 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
541#define DEFINE_EVENT_CONDITION(template, name, proto, \
542 args, cond) \
543 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
544 PARAMS(args), PARAMS(cond))
545
546#define TRACE_EVENT(name, proto, args, struct, assign, print) \
547 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
548#define TRACE_EVENT_FN(name, proto, args, struct, \
549 assign, print, reg, unreg) \
550 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
551#define TRACE_EVENT_FN_COND(name, proto, args, cond, struct, \
552 assign, print, reg, unreg) \
553 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
554 PARAMS(args), PARAMS(cond))
555#define TRACE_EVENT_CONDITION(name, proto, args, cond, \
556 struct, assign, print) \
557 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
558 PARAMS(args), PARAMS(cond))
559
560#define TRACE_EVENT_FLAGS(event, flag)
561
562#define TRACE_EVENT_PERF_PERM(event, expr...)
563
564#define DECLARE_EVENT_NOP(name, proto, args) \
565 static inline void trace_##name(proto) \
566 { } \
567 static inline bool trace_##name##_enabled(void) \
568 { \
569 return false; \
570 }
571
572#define TRACE_EVENT_NOP(name, proto, args, struct, assign, print) \
573 DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
574
575#define DECLARE_EVENT_CLASS_NOP(name, proto, args, tstruct, assign, print)
576#define DEFINE_EVENT_NOP(template, name, proto, args) \
577 DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
578
579#endif
580