blob: c6c61d6fc5263ed1a5a7517ca98f9dc5af07d23e [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001#ifndef _LINUX_TRACEPOINT_H
2#define _LINUX_TRACEPOINT_H
3
4/*
5 * Kernel Tracepoint API.
6 *
7 * See Documentation/trace/tracepoints.txt.
8 *
9 * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
10 *
11 * Heavily inspired from the Linux Kernel Markers.
12 *
13 * This file is released under the GPLv2.
14 * See the file COPYING for more details.
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
38extern int tracepoint_probe_register(const char *name, void *probe, void *data);
39
40extern int
41tracepoint_probe_unregister(const char *name, void *probe, void *data);
42
43extern int tracepoint_probe_register_noupdate(const char *name, void *probe,
44 void *data);
45extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
46 void *data);
47extern void tracepoint_probe_update_all(void);
48
49#ifdef CONFIG_MODULES
50struct tp_module {
51 struct list_head list;
52 unsigned int num_tracepoints;
53 struct tracepoint * const *tracepoints_ptrs;
54};
55#endif
56
57struct tracepoint_iter {
58#ifdef CONFIG_MODULES
59 struct tp_module *module;
60#endif
61 struct tracepoint * const *tracepoint;
62};
63
64extern void tracepoint_iter_start(struct tracepoint_iter *iter);
65extern void tracepoint_iter_next(struct tracepoint_iter *iter);
66extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
67extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
68
69static inline void tracepoint_synchronize_unregister(void)
70{
71 synchronize_sched();
72}
73
74#define PARAMS(args...) args
75
76#endif
77
78
79#ifndef DECLARE_TRACE
80
81#define TP_PROTO(args...) args
82#define TP_ARGS(args...) args
83#define TP_CONDITION(args...) args
84
85#ifdef CONFIG_TRACEPOINTS
86
87#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu) \
88 do { \
89 struct tracepoint_func *it_func_ptr; \
90 void *it_func; \
91 void *__data; \
92 \
93 if (!(cond)) \
94 return; \
95 prercu; \
96 rcu_read_lock_sched_notrace(); \
97 it_func_ptr = rcu_dereference_sched((tp)->funcs); \
98 if (it_func_ptr) { \
99 do { \
100 it_func = (it_func_ptr)->func; \
101 __data = (it_func_ptr)->data; \
102 ((void(*)(proto))(it_func))(args); \
103 } while ((++it_func_ptr)->func); \
104 } \
105 rcu_read_unlock_sched_notrace(); \
106 postrcu; \
107 } while (0)
108
109#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
110 extern struct tracepoint __tracepoint_##name; \
111 static inline void trace_##name(proto) \
112 { \
113 if (static_key_false(&__tracepoint_##name.key)) \
114 __DO_TRACE(&__tracepoint_##name, \
115 TP_PROTO(data_proto), \
116 TP_ARGS(data_args), \
117 TP_CONDITION(cond),,); \
118 } \
119 static inline void trace_##name##_rcuidle(proto) \
120 { \
121 if (static_branch(&__tracepoint_##name.key)) \
122 __DO_TRACE(&__tracepoint_##name, \
123 TP_PROTO(data_proto), \
124 TP_ARGS(data_args), \
125 TP_CONDITION(cond), \
126 rcu_idle_exit(), \
127 rcu_idle_enter()); \
128 } \
129 static inline int \
130 register_trace_##name(void (*probe)(data_proto), void *data) \
131 { \
132 return tracepoint_probe_register(#name, (void *)probe, \
133 data); \
134 } \
135 static inline int \
136 unregister_trace_##name(void (*probe)(data_proto), void *data) \
137 { \
138 return tracepoint_probe_unregister(#name, (void *)probe, \
139 data); \
140 } \
141 static inline void \
142 check_trace_callback_type_##name(void (*cb)(data_proto)) \
143 { \
144 }
145
146#define DEFINE_TRACE_FN(name, reg, unreg) \
147 static const char __tpstrtab_##name[] \
148 __attribute__((section("__tracepoints_strings"))) = #name; \
149 struct tracepoint __tracepoint_##name \
150 __attribute__((section("__tracepoints"))) = \
151 { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
152 static struct tracepoint * const __tracepoint_ptr_##name __used \
153 __attribute__((section("__tracepoints_ptrs"))) = \
154 &__tracepoint_##name;
155
156#define DEFINE_TRACE(name) \
157 DEFINE_TRACE_FN(name, NULL, NULL);
158
159#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
160 EXPORT_SYMBOL_GPL(__tracepoint_##name)
161#define EXPORT_TRACEPOINT_SYMBOL(name) \
162 EXPORT_SYMBOL(__tracepoint_##name)
163
164#else
165#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
166 static inline void trace_##name(proto) \
167 { } \
168 static inline void trace_##name##_rcuidle(proto) \
169 { } \
170 static inline int \
171 register_trace_##name(void (*probe)(data_proto), \
172 void *data) \
173 { \
174 return -ENOSYS; \
175 } \
176 static inline int \
177 unregister_trace_##name(void (*probe)(data_proto), \
178 void *data) \
179 { \
180 return -ENOSYS; \
181 } \
182 static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \
183 { \
184 }
185
186#define DEFINE_TRACE_FN(name, reg, unreg)
187#define DEFINE_TRACE(name)
188#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
189#define EXPORT_TRACEPOINT_SYMBOL(name)
190
191#endif
192
193#define DECLARE_TRACE_NOARGS(name) \
194 __DECLARE_TRACE(name, void, , 1, void *__data, __data)
195
196#define DECLARE_TRACE(name, proto, args) \
197 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \
198 PARAMS(void *__data, proto), \
199 PARAMS(__data, args))
200
201#define DECLARE_TRACE_CONDITION(name, proto, args, cond) \
202 __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
203 PARAMS(void *__data, proto), \
204 PARAMS(__data, args))
205
206#define TRACE_EVENT_FLAGS(event, flag)
207
208#endif
209
210#ifndef TRACE_EVENT
211
212#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
213#define DEFINE_EVENT(template, name, proto, args) \
214 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
215#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \
216 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
217#define DEFINE_EVENT_CONDITION(template, name, proto, \
218 args, cond) \
219 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
220 PARAMS(args), PARAMS(cond))
221
222#define TRACE_EVENT(name, proto, args, struct, assign, print) \
223 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
224#define TRACE_EVENT_FN(name, proto, args, struct, \
225 assign, print, reg, unreg) \
226 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
227#define TRACE_EVENT_CONDITION(name, proto, args, cond, \
228 struct, assign, print) \
229 DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
230 PARAMS(args), PARAMS(cond))
231
232#define TRACE_EVENT_FLAGS(event, flag)
233
234#endif