0001
0002 #ifndef _LINUX_TRACEPOINT_H
0003 #define _LINUX_TRACEPOINT_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/smp.h>
0016 #include <linux/srcu.h>
0017 #include <linux/errno.h>
0018 #include <linux/types.h>
0019 #include <linux/cpumask.h>
0020 #include <linux/rcupdate.h>
0021 #include <linux/tracepoint-defs.h>
0022 #include <linux/static_call.h>
0023
0024 struct module;
0025 struct tracepoint;
0026 struct notifier_block;
0027
0028 struct trace_eval_map {
0029 const char *system;
0030 const char *eval_string;
0031 unsigned long eval_value;
0032 };
0033
0034 #define TRACEPOINT_DEFAULT_PRIO 10
0035
0036 extern struct srcu_struct tracepoint_srcu;
0037
0038 extern int
0039 tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
0040 extern int
0041 tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data,
0042 int prio);
0043 extern int
0044 tracepoint_probe_register_prio_may_exist(struct tracepoint *tp, void *probe, void *data,
0045 int prio);
0046 extern int
0047 tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);
0048 static inline int
0049 tracepoint_probe_register_may_exist(struct tracepoint *tp, void *probe,
0050 void *data)
0051 {
0052 return tracepoint_probe_register_prio_may_exist(tp, probe, data,
0053 TRACEPOINT_DEFAULT_PRIO);
0054 }
0055 extern void
0056 for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv),
0057 void *priv);
0058
0059 #ifdef CONFIG_MODULES
0060 struct tp_module {
0061 struct list_head list;
0062 struct module *mod;
0063 };
0064
0065 bool trace_module_has_bad_taint(struct module *mod);
0066 extern int register_tracepoint_module_notifier(struct notifier_block *nb);
0067 extern int unregister_tracepoint_module_notifier(struct notifier_block *nb);
0068 #else
0069 static inline bool trace_module_has_bad_taint(struct module *mod)
0070 {
0071 return false;
0072 }
0073 static inline
0074 int register_tracepoint_module_notifier(struct notifier_block *nb)
0075 {
0076 return 0;
0077 }
0078 static inline
0079 int unregister_tracepoint_module_notifier(struct notifier_block *nb)
0080 {
0081 return 0;
0082 }
0083 #endif
0084
0085
0086
0087
0088
0089
0090 #ifdef CONFIG_TRACEPOINTS
0091 static inline void tracepoint_synchronize_unregister(void)
0092 {
0093 synchronize_srcu(&tracepoint_srcu);
0094 synchronize_rcu();
0095 }
0096 #else
0097 static inline void tracepoint_synchronize_unregister(void)
0098 { }
0099 #endif
0100
0101 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
0102 extern int syscall_regfunc(void);
0103 extern void syscall_unregfunc(void);
0104 #endif
0105
0106 #ifndef PARAMS
0107 #define PARAMS(args...) args
0108 #endif
0109
0110 #define TRACE_DEFINE_ENUM(x)
0111 #define TRACE_DEFINE_SIZEOF(x)
0112
0113 #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
0114 static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
0115 {
0116 return offset_to_ptr(p);
0117 }
0118
0119 #define __TRACEPOINT_ENTRY(name) \
0120 asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \
0121 " .balign 4 \n" \
0122 " .long __tracepoint_" #name " - . \n" \
0123 " .previous \n")
0124 #else
0125 static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
0126 {
0127 return *p;
0128 }
0129
0130 #define __TRACEPOINT_ENTRY(name) \
0131 static tracepoint_ptr_t __tracepoint_ptr_##name __used \
0132 __section("__tracepoints_ptrs") = &__tracepoint_##name
0133 #endif
0134
0135 #endif
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 #ifndef DECLARE_TRACE
0146
0147 #define TP_PROTO(args...) args
0148 #define TP_ARGS(args...) args
0149 #define TP_CONDITION(args...) args
0150
0151
0152
0153
0154
0155
0156
0157
0158 #if defined(CONFIG_TRACEPOINTS) && !defined(NOTRACE)
0159 #define TRACEPOINTS_ENABLED
0160 #endif
0161
0162 #ifdef TRACEPOINTS_ENABLED
0163
0164 #ifdef CONFIG_HAVE_STATIC_CALL
0165 #define __DO_TRACE_CALL(name, args) \
0166 do { \
0167 struct tracepoint_func *it_func_ptr; \
0168 void *__data; \
0169 it_func_ptr = \
0170 rcu_dereference_raw((&__tracepoint_##name)->funcs); \
0171 if (it_func_ptr) { \
0172 __data = (it_func_ptr)->data; \
0173 static_call(tp_func_##name)(__data, args); \
0174 } \
0175 } while (0)
0176 #else
0177 #define __DO_TRACE_CALL(name, args) __traceiter_##name(NULL, args)
0178 #endif
0179
0180
0181
0182
0183
0184 #define __DO_TRACE(name, args, cond, rcuidle) \
0185 do { \
0186 int __maybe_unused __idx = 0; \
0187 \
0188 if (!(cond)) \
0189 return; \
0190 \
0191 \
0192 WARN_ON_ONCE(rcuidle && in_nmi()); \
0193 \
0194 \
0195 preempt_disable_notrace(); \
0196 \
0197
0198
0199
0200 \
0201 if (rcuidle) { \
0202 __idx = srcu_read_lock_notrace(&tracepoint_srcu);\
0203 ct_irq_enter_irqson(); \
0204 } \
0205 \
0206 __DO_TRACE_CALL(name, TP_ARGS(args)); \
0207 \
0208 if (rcuidle) { \
0209 ct_irq_exit_irqson(); \
0210 srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\
0211 } \
0212 \
0213 preempt_enable_notrace(); \
0214 } while (0)
0215
0216 #ifndef MODULE
0217 #define __DECLARE_TRACE_RCU(name, proto, args, cond) \
0218 static inline void trace_##name##_rcuidle(proto) \
0219 { \
0220 if (static_key_false(&__tracepoint_##name.key)) \
0221 __DO_TRACE(name, \
0222 TP_ARGS(args), \
0223 TP_CONDITION(cond), 1); \
0224 }
0225 #else
0226 #define __DECLARE_TRACE_RCU(name, proto, args, cond)
0227 #endif
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
0242 extern int __traceiter_##name(data_proto); \
0243 DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
0244 extern struct tracepoint __tracepoint_##name; \
0245 static inline void trace_##name(proto) \
0246 { \
0247 if (static_key_false(&__tracepoint_##name.key)) \
0248 __DO_TRACE(name, \
0249 TP_ARGS(args), \
0250 TP_CONDITION(cond), 0); \
0251 if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
0252 rcu_read_lock_sched_notrace(); \
0253 rcu_dereference_sched(__tracepoint_##name.funcs);\
0254 rcu_read_unlock_sched_notrace(); \
0255 } \
0256 } \
0257 __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
0258 PARAMS(cond)) \
0259 static inline int \
0260 register_trace_##name(void (*probe)(data_proto), void *data) \
0261 { \
0262 return tracepoint_probe_register(&__tracepoint_##name, \
0263 (void *)probe, data); \
0264 } \
0265 static inline int \
0266 register_trace_prio_##name(void (*probe)(data_proto), void *data,\
0267 int prio) \
0268 { \
0269 return tracepoint_probe_register_prio(&__tracepoint_##name, \
0270 (void *)probe, data, prio); \
0271 } \
0272 static inline int \
0273 unregister_trace_##name(void (*probe)(data_proto), void *data) \
0274 { \
0275 return tracepoint_probe_unregister(&__tracepoint_##name,\
0276 (void *)probe, data); \
0277 } \
0278 static inline void \
0279 check_trace_callback_type_##name(void (*cb)(data_proto)) \
0280 { \
0281 } \
0282 static inline bool \
0283 trace_##name##_enabled(void) \
0284 { \
0285 return static_key_false(&__tracepoint_##name.key); \
0286 }
0287
0288
0289
0290
0291
0292
0293 #define DEFINE_TRACE_FN(_name, _reg, _unreg, proto, args) \
0294 static const char __tpstrtab_##_name[] \
0295 __section("__tracepoints_strings") = #_name; \
0296 extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \
0297 int __traceiter_##_name(void *__data, proto); \
0298 struct tracepoint __tracepoint_##_name __used \
0299 __section("__tracepoints") = { \
0300 .name = __tpstrtab_##_name, \
0301 .key = STATIC_KEY_INIT_FALSE, \
0302 .static_call_key = &STATIC_CALL_KEY(tp_func_##_name), \
0303 .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
0304 .iterator = &__traceiter_##_name, \
0305 .regfunc = _reg, \
0306 .unregfunc = _unreg, \
0307 .funcs = NULL }; \
0308 __TRACEPOINT_ENTRY(_name); \
0309 int __traceiter_##_name(void *__data, proto) \
0310 { \
0311 struct tracepoint_func *it_func_ptr; \
0312 void *it_func; \
0313 \
0314 it_func_ptr = \
0315 rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
0316 if (it_func_ptr) { \
0317 do { \
0318 it_func = READ_ONCE((it_func_ptr)->func); \
0319 __data = (it_func_ptr)->data; \
0320 ((void(*)(void *, proto))(it_func))(__data, args); \
0321 } while ((++it_func_ptr)->func); \
0322 } \
0323 return 0; \
0324 } \
0325 DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
0326
0327 #define DEFINE_TRACE(name, proto, args) \
0328 DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args));
0329
0330 #define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
0331 EXPORT_SYMBOL_GPL(__tracepoint_##name); \
0332 EXPORT_SYMBOL_GPL(__traceiter_##name); \
0333 EXPORT_STATIC_CALL_GPL(tp_func_##name)
0334 #define EXPORT_TRACEPOINT_SYMBOL(name) \
0335 EXPORT_SYMBOL(__tracepoint_##name); \
0336 EXPORT_SYMBOL(__traceiter_##name); \
0337 EXPORT_STATIC_CALL(tp_func_##name)
0338
0339
0340 #else
0341 #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
0342 static inline void trace_##name(proto) \
0343 { } \
0344 static inline void trace_##name##_rcuidle(proto) \
0345 { } \
0346 static inline int \
0347 register_trace_##name(void (*probe)(data_proto), \
0348 void *data) \
0349 { \
0350 return -ENOSYS; \
0351 } \
0352 static inline int \
0353 unregister_trace_##name(void (*probe)(data_proto), \
0354 void *data) \
0355 { \
0356 return -ENOSYS; \
0357 } \
0358 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
0359 { \
0360 } \
0361 static inline bool \
0362 trace_##name##_enabled(void) \
0363 { \
0364 return false; \
0365 }
0366
0367 #define DEFINE_TRACE_FN(name, reg, unreg, proto, args)
0368 #define DEFINE_TRACE(name, proto, args)
0369 #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
0370 #define EXPORT_TRACEPOINT_SYMBOL(name)
0371
0372 #endif
0373
0374 #ifdef CONFIG_TRACING
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402 #define tracepoint_string(str) \
0403 ({ \
0404 static const char *___tp_str __tracepoint_string = str; \
0405 ___tp_str; \
0406 })
0407 #define __tracepoint_string __used __section("__tracepoint_str")
0408 #else
0409
0410
0411
0412
0413
0414 # define tracepoint_string(str) str
0415 # define __tracepoint_string
0416 #endif
0417
0418 #define DECLARE_TRACE(name, proto, args) \
0419 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
0420 cpu_online(raw_smp_processor_id()), \
0421 PARAMS(void *__data, proto))
0422
0423 #define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
0424 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
0425 cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
0426 PARAMS(void *__data, proto))
0427
0428 #define TRACE_EVENT_FLAGS(event, flag)
0429
0430 #define TRACE_EVENT_PERF_PERM(event, expr...)
0431
0432 #endif
0433
0434 #ifndef TRACE_EVENT
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540 #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
0541 #define DEFINE_EVENT(template, name, proto, args) \
0542 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
0543 #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
0544 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
0545 #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
0546 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
0547 #define DEFINE_EVENT_CONDITION(template, name, proto, \
0548 args, cond) \
0549 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
0550 PARAMS(args), PARAMS(cond))
0551
0552 #define TRACE_EVENT(name, proto, args, struct, assign, print) \
0553 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
0554 #define TRACE_EVENT_FN(name, proto, args, struct, \
0555 assign, print, reg, unreg) \
0556 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
0557 #define TRACE_EVENT_FN_COND(name, proto, args, cond, struct, \
0558 assign, print, reg, unreg) \
0559 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
0560 PARAMS(args), PARAMS(cond))
0561 #define TRACE_EVENT_CONDITION(name, proto, args, cond, \
0562 struct, assign, print) \
0563 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
0564 PARAMS(args), PARAMS(cond))
0565
0566 #define TRACE_EVENT_FLAGS(event, flag)
0567
0568 #define TRACE_EVENT_PERF_PERM(event, expr...)
0569
0570 #define DECLARE_EVENT_NOP(name, proto, args) \
0571 static inline void trace_##name(proto) \
0572 { } \
0573 static inline bool trace_##name##_enabled(void) \
0574 { \
0575 return false; \
0576 }
0577
0578 #define TRACE_EVENT_NOP(name, proto, args, struct, assign, print) \
0579 DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
0580
0581 #define DECLARE_EVENT_CLASS_NOP(name, proto, args, tstruct, assign, print)
0582 #define DEFINE_EVENT_NOP(template, name, proto, args) \
0583 DECLARE_EVENT_NOP(name, PARAMS(proto), PARAMS(args))
0584
0585 #endif