1#ifndef _LINUX_TRACEPOINT_H
2#define _LINUX_TRACEPOINT_H
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/errno.h>
18#include <linux/types.h>
19#include <linux/rcupdate.h>
20#include <linux/static_key.h>
21
22struct module;
23struct tracepoint;
24
25struct tracepoint_func {
26 void *func;
27 void *data;
28};
29
30struct tracepoint {
31 const char *name;
32 struct static_key key;
33 void (*regfunc)(void);
34 void (*unregfunc)(void);
35 struct tracepoint_func __rcu *funcs;
36};
37
38struct trace_enum_map {
39 const char *system;
40 const char *enum_string;
41 unsigned long enum_value;
42};
43
44
45
46
47
48extern int tracepoint_probe_register(const char *name, void *probe, void *data);
49
50
51
52
53
54extern int
55tracepoint_probe_unregister(const char *name, void *probe, void *data);
56
57extern int tracepoint_probe_register_noupdate(const char *name, void *probe,
58 void *data);
59extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
60 void *data);
61extern void tracepoint_probe_update_all(void);
62
63#ifdef CONFIG_MODULES
64struct tp_module {
65 struct list_head list;
66 unsigned int num_tracepoints;
67 struct tracepoint * const *tracepoints_ptrs;
68};
69bool trace_module_has_bad_taint(struct module *mod);
70#else
71static inline bool trace_module_has_bad_taint(struct module *mod)
72{
73 return false;
74}
75#endif
76
77struct tracepoint_iter {
78#ifdef CONFIG_MODULES
79 struct tp_module *module;
80#endif
81 struct tracepoint * const *tracepoint;
82};
83
84extern void tracepoint_iter_start(struct tracepoint_iter *iter);
85extern void tracepoint_iter_next(struct tracepoint_iter *iter);
86extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
87extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
88
89
90
91
92
93
94static inline void tracepoint_synchronize_unregister(void)
95{
96 synchronize_sched();
97}
98
99#define PARAMS(args...) args
100
101#define TRACE_DEFINE_ENUM(x)
102
103#endif
104
105
106
107
108
109
110
111
112
113#ifndef DECLARE_TRACE
114
115#define TP_PROTO(args...) args
116#define TP_ARGS(args...) args
117#define TP_CONDITION(args...) args
118
119#ifdef CONFIG_TRACEPOINTS
120
121
122
123
124
125
126
127
128
129
130
131#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu) \
132 do { \
133 struct tracepoint_func *it_func_ptr; \
134 void *it_func; \
135 void *__data; \
136 \
137 if (!(cond)) \
138 return; \
139 prercu; \
140 rcu_read_lock_sched_notrace(); \
141 it_func_ptr = rcu_dereference_sched((tp)->funcs); \
142 if (it_func_ptr) { \
143 do { \
144 it_func = (it_func_ptr)->func; \
145 __data = (it_func_ptr)->data; \
146 ((void(*)(proto))(it_func))(args); \
147 } while ((++it_func_ptr)->func); \
148 } \
149 rcu_read_unlock_sched_notrace(); \
150 postrcu; \
151 } while (0)
152
153#ifndef MODULE
154#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) \
155 static inline void trace_##name##_rcuidle(proto) \
156 { \
157 if (static_key_false(&__tracepoint_##name.key)) \
158 __DO_TRACE(&__tracepoint_##name, \
159 TP_PROTO(data_proto), \
160 TP_ARGS(data_args), \
161 TP_CONDITION(cond), \
162 rcu_irq_enter(), \
163 rcu_irq_exit()); \
164 }
165#else
166#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)
167#endif
168
169
170
171
172
173
174#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
175 extern struct tracepoint __tracepoint_##name; \
176 static inline void trace_##name(proto) \
177 { \
178 if (static_key_false(&__tracepoint_##name.key)) \
179 __DO_TRACE(&__tracepoint_##name, \
180 TP_PROTO(data_proto), \
181 TP_ARGS(data_args), \
182 TP_CONDITION(cond),,); \
183 } \
184 __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
185 PARAMS(cond), PARAMS(data_proto), PARAMS(data_args)) \
186 static inline int \
187 register_trace_##name(void (*probe)(data_proto), void *data) \
188 { \
189 return tracepoint_probe_register(#name, (void *)probe, \
190 data); \
191 } \
192 static inline int \
193 unregister_trace_##name(void (*probe)(data_proto), void *data) \
194 { \
195 return tracepoint_probe_unregister(#name, (void *)probe, \
196 data); \
197 } \
198 static inline void \
199 check_trace_callback_type_##name(void (*cb)(data_proto)) \
200 { \
201 } \
202 static inline bool \
203 trace_##name##_enabled(void) \
204 { \
205 return static_key_false(&__tracepoint_##name.key); \
206 }
207
208
209
210
211
212
213#define DEFINE_TRACE_FN(name, reg, unreg) \
214 static const char __tpstrtab_##name[] \
215 __attribute__((section("__tracepoints_strings"))) = #name; \
216 struct tracepoint __tracepoint_##name \
217 __attribute__((section("__tracepoints"))) = \
218 { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
219 static struct tracepoint * const __tracepoint_ptr_##name __used \
220 __attribute__((section("__tracepoints_ptrs"))) = \
221 &__tracepoint_##name;
222
223#define DEFINE_TRACE(name) \
224 DEFINE_TRACE_FN(name, NULL, NULL);
225
226#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
227 EXPORT_SYMBOL_GPL(__tracepoint_##name)
228#define EXPORT_TRACEPOINT_SYMBOL(name) \
229 EXPORT_SYMBOL(__tracepoint_##name)
230
231#else
232#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
233 static inline void trace_##name(proto) \
234 { } \
235 static inline void trace_##name##_rcuidle(proto) \
236 { } \
237 static inline int \
238 register_trace_##name(void (*probe)(data_proto), \
239 void *data) \
240 { \
241 return -ENOSYS; \
242 } \
243 static inline int \
244 unregister_trace_##name(void (*probe)(data_proto), \
245 void *data) \
246 { \
247 return -ENOSYS; \
248 } \
249 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
250 { \
251 } \
252 static inline bool \
253 trace_##name##_enabled(void) \
254 { \
255 return false; \
256 }
257
258#define DEFINE_TRACE_FN(name, reg, unreg)
259#define DEFINE_TRACE(name)
260#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
261#define EXPORT_TRACEPOINT_SYMBOL(name)
262
263#endif
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279#define DECLARE_TRACE_NOARGS(name) \
280 __DECLARE_TRACE(name, void, , 1, void *__data, __data)
281
282#define DECLARE_TRACE(name, proto, args) \
283 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \
284 PARAMS(void *__data, proto), \
285 PARAMS(__data, args))
286
287#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
288 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
289 PARAMS(void *__data, proto), \
290 PARAMS(__data, args))
291
292#define TRACE_EVENT_FLAGS(event, flag)
293
294#endif
295
296#ifndef TRACE_EVENT
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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
395
396
397
398
399
400
401
402#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
403#define DEFINE_EVENT(template, name, proto, args) \
404 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
405#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
406 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
407#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
408 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
409#define DEFINE_EVENT_CONDITION(template, name, proto, \
410 args, cond) \
411 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
412 PARAMS(args), PARAMS(cond))
413
414#define TRACE_EVENT(name, proto, args, struct, assign, print) \
415 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
416#define TRACE_EVENT_FN(name, proto, args, struct, \
417 assign, print, reg, unreg) \
418 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
419#define TRACE_EVENT_CONDITION(name, proto, args, cond, \
420 struct, assign, print) \
421 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
422 PARAMS(args), PARAMS(cond))
423
424#define TRACE_EVENT_FLAGS(event, flag)
425
426#endif
427