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
140
141
142
143
144#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
145 extern struct tracepoint __tracepoint_##name; \
146 static inline void trace_##name(proto) \
147 { \
148 if (static_key_false(&__tracepoint_##name.key)) \
149 __DO_TRACE(&__tracepoint_##name, \
150 TP_PROTO(data_proto), \
151 TP_ARGS(data_args), \
152 TP_CONDITION(cond),,); \
153 } \
154 static inline void trace_##name##_rcuidle(proto) \
155 { \
156 if (static_key_false(&__tracepoint_##name.key)) \
157 __DO_TRACE(&__tracepoint_##name, \
158 TP_PROTO(data_proto), \
159 TP_ARGS(data_args), \
160 TP_CONDITION(cond), \
161 rcu_idle_exit(), \
162 rcu_idle_enter()); \
163 } \
164 static inline int \
165 register_trace_##name(void (*probe)(data_proto), void *data) \
166 { \
167 return tracepoint_probe_register(#name, (void *)probe, \
168 data); \
169 } \
170 static inline int \
171 unregister_trace_##name(void (*probe)(data_proto), void *data) \
172 { \
173 return tracepoint_probe_unregister(#name, (void *)probe, \
174 data); \
175 } \
176 static inline void \
177 check_trace_callback_type_##name(void (*cb)(data_proto)) \
178 { \
179 }
180
181
182
183
184
185
186#define DEFINE_TRACE_FN(name, reg, unreg) \
187 static const char __tpstrtab_##name[] \
188 __attribute__((section("__tracepoints_strings"))) = #name; \
189 struct tracepoint __tracepoint_##name \
190 __attribute__((section("__tracepoints"))) = \
191 { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
192 static struct tracepoint * const __tracepoint_ptr_##name __used \
193 __attribute__((section("__tracepoints_ptrs"))) = \
194 &__tracepoint_##name;
195
196#define DEFINE_TRACE(name) \
197 DEFINE_TRACE_FN(name, NULL, NULL);
198
199#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
200 EXPORT_SYMBOL_GPL(__tracepoint_##name)
201#define EXPORT_TRACEPOINT_SYMBOL(name) \
202 EXPORT_SYMBOL(__tracepoint_##name)
203
204#else
205#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
206 static inline void trace_##name(proto) \
207 { } \
208 static inline void trace_##name##_rcuidle(proto) \
209 { } \
210 static inline int \
211 register_trace_##name(void (*probe)(data_proto), \
212 void *data) \
213 { \
214 return -ENOSYS; \
215 } \
216 static inline int \
217 unregister_trace_##name(void (*probe)(data_proto), \
218 void *data) \
219 { \
220 return -ENOSYS; \
221 } \
222 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
223 { \
224 }
225
226#define DEFINE_TRACE_FN(name, reg, unreg)
227#define DEFINE_TRACE(name)
228#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
229#define EXPORT_TRACEPOINT_SYMBOL(name)
230
231#endif
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247#define DECLARE_TRACE_NOARGS(name) \
248 __DECLARE_TRACE(name, void, , 1, void *__data, __data)
249
250#define DECLARE_TRACE(name, proto, args) \
251 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \
252 PARAMS(void *__data, proto), \
253 PARAMS(__data, args))
254
255#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
256 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
257 PARAMS(void *__data, proto), \
258 PARAMS(__data, args))
259
260#define TRACE_EVENT_FLAGS(event, flag)
261
262#endif
263
264#ifndef TRACE_EVENT
265
266
267
268
269
270
271
272
273
274
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#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
371#define DEFINE_EVENT(template, name, proto, args) \
372 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
373#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
374 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
375#define DEFINE_EVENT_CONDITION(template, name, proto, \
376 args, cond) \
377 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
378 PARAMS(args), PARAMS(cond))
379
380#define TRACE_EVENT(name, proto, args, struct, assign, print) \
381 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
382#define TRACE_EVENT_FN(name, proto, args, struct, \
383 assign, print, reg, unreg) \
384 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
385#define TRACE_EVENT_CONDITION(name, proto, args, cond, \
386 struct, assign, print) \
387 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
388 PARAMS(args), PARAMS(cond))
389
390#define TRACE_EVENT_FLAGS(event, flag)
391
392#endif
393