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