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
38
39
40
41
42extern int tracepoint_probe_register(const char *name, void *probe, void *data);
43
44
45
46
47
48extern int
49tracepoint_probe_unregister(const char *name, void *probe, void *data);
50
51extern int tracepoint_probe_register_noupdate(const char *name, void *probe,
52 void *data);
53extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
54 void *data);
55extern void tracepoint_probe_update_all(void);
56
57#ifdef CONFIG_MODULES
58struct tp_module {
59 struct list_head list;
60 unsigned int num_tracepoints;
61 struct tracepoint * const *tracepoints_ptrs;
62};
63bool trace_module_has_bad_taint(struct module *mod);
64#else
65static inline bool trace_module_has_bad_taint(struct module *mod)
66{
67 return false;
68}
69#endif
70
71struct tracepoint_iter {
72#ifdef CONFIG_MODULES
73 struct tp_module *module;
74#endif
75 struct tracepoint * const *tracepoint;
76};
77
78extern void tracepoint_iter_start(struct tracepoint_iter *iter);
79extern void tracepoint_iter_next(struct tracepoint_iter *iter);
80extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
81extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
82
83
84
85
86
87
88static inline void tracepoint_synchronize_unregister(void)
89{
90 synchronize_sched();
91}
92
93#define PARAMS(args...) args
94
95#endif
96
97
98
99
100
101
102
103
104
105#ifndef DECLARE_TRACE
106
107#define TP_PROTO(args...) args
108#define TP_ARGS(args...) args
109#define TP_CONDITION(args...) args
110
111#ifdef CONFIG_TRACEPOINTS
112
113
114
115
116
117
118
119
120
121
122
123#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu) \
124 do { \
125 struct tracepoint_func *it_func_ptr; \
126 void *it_func; \
127 void *__data; \
128 \
129 if (!(cond)) \
130 return; \
131 prercu; \
132 rcu_read_lock_sched_notrace(); \
133 it_func_ptr = rcu_dereference_sched((tp)->funcs); \
134 if (it_func_ptr) { \
135 do { \
136 it_func = (it_func_ptr)->func; \
137 __data = (it_func_ptr)->data; \
138 ((void(*)(proto))(it_func))(args); \
139 } while ((++it_func_ptr)->func); \
140 } \
141 rcu_read_unlock_sched_notrace(); \
142 postrcu; \
143 } while (0)
144
145#ifndef MODULE
146#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) \
147 static inline void trace_##name##_rcuidle(proto) \
148 { \
149 if (static_key_false(&__tracepoint_##name.key)) \
150 __DO_TRACE(&__tracepoint_##name, \
151 TP_PROTO(data_proto), \
152 TP_ARGS(data_args), \
153 TP_CONDITION(cond), \
154 rcu_irq_enter(), \
155 rcu_irq_exit()); \
156 }
157#else
158#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)
159#endif
160
161
162
163
164
165
166#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
167 extern struct tracepoint __tracepoint_##name; \
168 static inline void trace_##name(proto) \
169 { \
170 if (static_key_false(&__tracepoint_##name.key)) \
171 __DO_TRACE(&__tracepoint_##name, \
172 TP_PROTO(data_proto), \
173 TP_ARGS(data_args), \
174 TP_CONDITION(cond),,); \
175 } \
176 __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
177 PARAMS(cond), PARAMS(data_proto), PARAMS(data_args)) \
178 static inline int \
179 register_trace_##name(void (*probe)(data_proto), void *data) \
180 { \
181 return tracepoint_probe_register(#name, (void *)probe, \
182 data); \
183 } \
184 static inline int \
185 unregister_trace_##name(void (*probe)(data_proto), void *data) \
186 { \
187 return tracepoint_probe_unregister(#name, (void *)probe, \
188 data); \
189 } \
190 static inline void \
191 check_trace_callback_type_##name(void (*cb)(data_proto)) \
192 { \
193 }
194
195
196
197
198
199
200#define DEFINE_TRACE_FN(name, reg, unreg) \
201 static const char __tpstrtab_##name[] \
202 __attribute__((section("__tracepoints_strings"))) = #name; \
203 struct tracepoint __tracepoint_##name \
204 __attribute__((section("__tracepoints"))) = \
205 { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
206 static struct tracepoint * const __tracepoint_ptr_##name __used \
207 __attribute__((section("__tracepoints_ptrs"))) = \
208 &__tracepoint_##name;
209
210#define DEFINE_TRACE(name) \
211 DEFINE_TRACE_FN(name, NULL, NULL);
212
213#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
214 EXPORT_SYMBOL_GPL(__tracepoint_##name)
215#define EXPORT_TRACEPOINT_SYMBOL(name) \
216 EXPORT_SYMBOL(__tracepoint_##name)
217
218#else
219#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
220 static inline void trace_##name(proto) \
221 { } \
222 static inline void trace_##name##_rcuidle(proto) \
223 { } \
224 static inline int \
225 register_trace_##name(void (*probe)(data_proto), \
226 void *data) \
227 { \
228 return -ENOSYS; \
229 } \
230 static inline int \
231 unregister_trace_##name(void (*probe)(data_proto), \
232 void *data) \
233 { \
234 return -ENOSYS; \
235 } \
236 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
237 { \
238 }
239
240#define DEFINE_TRACE_FN(name, reg, unreg)
241#define DEFINE_TRACE(name)
242#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
243#define EXPORT_TRACEPOINT_SYMBOL(name)
244
245#endif
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261#define DECLARE_TRACE_NOARGS(name) \
262 __DECLARE_TRACE(name, void, , 1, void *__data, __data)
263
264#define DECLARE_TRACE(name, proto, args) \
265 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \
266 PARAMS(void *__data, proto), \
267 PARAMS(__data, args))
268
269#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
270 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
271 PARAMS(void *__data, proto), \
272 PARAMS(__data, args))
273
274#define TRACE_EVENT_FLAGS(event, flag)
275
276#define TRACE_EVENT_PERF_PERM(event, expr...)
277
278#endif
279
280#ifndef TRACE_EVENT
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
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#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
387#define DEFINE_EVENT(template, name, proto, args) \
388 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
389#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\
390 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
391#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
392 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
393#define DEFINE_EVENT_CONDITION(template, name, proto, \
394 args, cond) \
395 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
396 PARAMS(args), PARAMS(cond))
397
398#define TRACE_EVENT(name, proto, args, struct, assign, print) \
399 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
400#define TRACE_EVENT_FN(name, proto, args, struct, \
401 assign, print, reg, unreg) \
402 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
403#define TRACE_EVENT_CONDITION(name, proto, args, cond, \
404 struct, assign, print) \
405 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
406 PARAMS(args), PARAMS(cond))
407
408#define TRACE_EVENT_FLAGS(event, flag)
409
410#define TRACE_EVENT_PERF_PERM(event, expr...)
411
412#endif
413