Commit | Line | Data |
---|---|---|
c32e827b SR |
1 | /* |
2 | * Stage 3 of the trace events. | |
3 | * | |
4 | * Override the macros in <trace/trace_event_types.h> to include the following: | |
5 | * | |
6 | * static void ftrace_event_<call>(proto) | |
7 | * { | |
ef18012b | 8 | * event_trace_printk(_RET_IP_, "<call>: " <fmt>); |
c32e827b SR |
9 | * } |
10 | * | |
11 | * static int ftrace_reg_event_<call>(void) | |
12 | * { | |
ef18012b | 13 | * int ret; |
c32e827b | 14 | * |
ef18012b SR |
15 | * ret = register_trace_<call>(ftrace_event_<call>); |
16 | * if (!ret) | |
17 | * pr_info("event trace: Could not activate trace point " | |
18 | * "probe to <call>"); | |
19 | * return ret; | |
c32e827b SR |
20 | * } |
21 | * | |
22 | * static void ftrace_unreg_event_<call>(void) | |
23 | * { | |
ef18012b | 24 | * unregister_trace_<call>(ftrace_event_<call>); |
c32e827b SR |
25 | * } |
26 | * | |
27 | * For those macros defined with TRACE_FORMAT: | |
28 | * | |
29 | * static struct ftrace_event_call __used | |
30 | * __attribute__((__aligned__(4))) | |
31 | * __attribute__((section("_ftrace_events"))) event_<call> = { | |
ef18012b SR |
32 | * .name = "<call>", |
33 | * .regfunc = ftrace_reg_event_<call>, | |
34 | * .unregfunc = ftrace_unreg_event_<call>, | |
c32e827b SR |
35 | * } |
36 | * | |
37 | * | |
157587d7 | 38 | * For those macros defined with TRACE_EVENT: |
c32e827b SR |
39 | * |
40 | * static struct ftrace_event_call event_<call>; | |
41 | * | |
42 | * static void ftrace_raw_event_<call>(proto) | |
43 | * { | |
ef18012b SR |
44 | * struct ring_buffer_event *event; |
45 | * struct ftrace_raw_<call> *entry; <-- defined in stage 1 | |
46 | * unsigned long irq_flags; | |
47 | * int pc; | |
48 | * | |
49 | * local_save_flags(irq_flags); | |
50 | * pc = preempt_count(); | |
51 | * | |
52 | * event = trace_current_buffer_lock_reserve(event_<call>.id, | |
53 | * sizeof(struct ftrace_raw_<call>), | |
54 | * irq_flags, pc); | |
55 | * if (!event) | |
56 | * return; | |
57 | * entry = ring_buffer_event_data(event); | |
58 | * | |
59 | * <assign>; <-- Here we assign the entries by the __field and | |
0e3d0f05 | 60 | * __array macros. |
c32e827b | 61 | * |
ef18012b | 62 | * trace_current_buffer_unlock_commit(event, irq_flags, pc); |
c32e827b SR |
63 | * } |
64 | * | |
65 | * static int ftrace_raw_reg_event_<call>(void) | |
66 | * { | |
ef18012b | 67 | * int ret; |
c32e827b | 68 | * |
ef18012b SR |
69 | * ret = register_trace_<call>(ftrace_raw_event_<call>); |
70 | * if (!ret) | |
71 | * pr_info("event trace: Could not activate trace point " | |
72 | * "probe to <call>"); | |
73 | * return ret; | |
c32e827b SR |
74 | * } |
75 | * | |
76 | * static void ftrace_unreg_event_<call>(void) | |
77 | * { | |
ef18012b | 78 | * unregister_trace_<call>(ftrace_raw_event_<call>); |
c32e827b SR |
79 | * } |
80 | * | |
81 | * static struct trace_event ftrace_event_type_<call> = { | |
ef18012b | 82 | * .trace = ftrace_raw_output_<call>, <-- stage 2 |
c32e827b SR |
83 | * }; |
84 | * | |
85 | * static int ftrace_raw_init_event_<call>(void) | |
86 | * { | |
ef18012b | 87 | * int id; |
c32e827b | 88 | * |
ef18012b SR |
89 | * id = register_ftrace_event(&ftrace_event_type_<call>); |
90 | * if (!id) | |
91 | * return -ENODEV; | |
92 | * event_<call>.id = id; | |
93 | * return 0; | |
c32e827b SR |
94 | * } |
95 | * | |
96 | * static struct ftrace_event_call __used | |
97 | * __attribute__((__aligned__(4))) | |
98 | * __attribute__((section("_ftrace_events"))) event_<call> = { | |
ef18012b | 99 | * .name = "<call>", |
0e3d0f05 | 100 | * .system = "<system>", |
ef18012b SR |
101 | * .raw_init = ftrace_raw_init_event_<call>, |
102 | * .regfunc = ftrace_reg_event_<call>, | |
103 | * .unregfunc = ftrace_unreg_event_<call>, | |
981d081e | 104 | * .show_format = ftrace_format_<call>, |
c32e827b SR |
105 | * } |
106 | * | |
107 | */ | |
108 | ||
2939b046 SR |
109 | #undef TP_FMT |
110 | #define TP_FMT(fmt, args...) fmt "\n", ##args | |
c32e827b | 111 | |
ac199db0 PZ |
112 | #ifdef CONFIG_EVENT_PROFILE |
113 | #define _TRACE_PROFILE(call, proto, args) \ | |
114 | static void ftrace_profile_##call(proto) \ | |
115 | { \ | |
116 | extern void perf_tpcounter_event(int); \ | |
117 | perf_tpcounter_event(event_##call.id); \ | |
118 | } \ | |
119 | \ | |
120 | static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \ | |
121 | { \ | |
122 | int ret = 0; \ | |
123 | \ | |
124 | if (!atomic_inc_return(&call->profile_count)) \ | |
125 | ret = register_trace_##call(ftrace_profile_##call); \ | |
126 | \ | |
127 | return ret; \ | |
128 | } \ | |
129 | \ | |
130 | static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \ | |
131 | { \ | |
132 | if (atomic_add_negative(-1, &call->profile_count)) \ | |
133 | unregister_trace_##call(ftrace_profile_##call); \ | |
134 | } | |
135 | ||
136 | #define _TRACE_PROFILE_INIT(call) \ | |
137 | .profile_count = ATOMIC_INIT(-1), \ | |
138 | .profile_enable = ftrace_profile_enable_##call, \ | |
139 | .profile_disable = ftrace_profile_disable_##call, | |
140 | ||
141 | #else | |
142 | #define _TRACE_PROFILE(call, proto, args) | |
143 | #define _TRACE_PROFILE_INIT(call) | |
144 | #endif | |
145 | ||
c32e827b SR |
146 | #define _TRACE_FORMAT(call, proto, args, fmt) \ |
147 | static void ftrace_event_##call(proto) \ | |
148 | { \ | |
efed792d | 149 | event_trace_printk(_RET_IP_, #call ": " fmt); \ |
c32e827b SR |
150 | } \ |
151 | \ | |
152 | static int ftrace_reg_event_##call(void) \ | |
153 | { \ | |
154 | int ret; \ | |
155 | \ | |
156 | ret = register_trace_##call(ftrace_event_##call); \ | |
633ddaa7 | 157 | if (ret) \ |
c32e827b | 158 | pr_info("event trace: Could not activate trace point " \ |
633ddaa7 | 159 | "probe to " #call "\n"); \ |
c32e827b SR |
160 | return ret; \ |
161 | } \ | |
162 | \ | |
163 | static void ftrace_unreg_event_##call(void) \ | |
164 | { \ | |
165 | unregister_trace_##call(ftrace_event_##call); \ | |
166 | } \ | |
28bea271 PZ |
167 | \ |
168 | static struct ftrace_event_call event_##call; \ | |
169 | \ | |
170 | static int ftrace_init_event_##call(void) \ | |
171 | { \ | |
172 | int id; \ | |
173 | \ | |
174 | id = register_ftrace_event(NULL); \ | |
175 | if (!id) \ | |
176 | return -ENODEV; \ | |
177 | event_##call.id = id; \ | |
178 | return 0; \ | |
179 | } | |
c32e827b SR |
180 | |
181 | #undef TRACE_FORMAT | |
182 | #define TRACE_FORMAT(call, proto, args, fmt) \ | |
183 | _TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \ | |
ac199db0 | 184 | _TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ |
c32e827b SR |
185 | static struct ftrace_event_call __used \ |
186 | __attribute__((__aligned__(4))) \ | |
187 | __attribute__((section("_ftrace_events"))) event_##call = { \ | |
ef18012b | 188 | .name = #call, \ |
9cc26a26 | 189 | .system = __stringify(TRACE_SYSTEM), \ |
28bea271 | 190 | .raw_init = ftrace_init_event_##call, \ |
c32e827b SR |
191 | .regfunc = ftrace_reg_event_##call, \ |
192 | .unregfunc = ftrace_unreg_event_##call, \ | |
ac199db0 | 193 | _TRACE_PROFILE_INIT(call) \ |
c32e827b SR |
194 | } |
195 | ||
da4d0302 SR |
196 | #undef __entry |
197 | #define __entry entry | |
d20e3b03 | 198 | |
da4d0302 | 199 | #undef TRACE_EVENT |
30a8fecc | 200 | #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ |
ac199db0 | 201 | _TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ |
c32e827b SR |
202 | \ |
203 | static struct ftrace_event_call event_##call; \ | |
204 | \ | |
205 | static void ftrace_raw_event_##call(proto) \ | |
206 | { \ | |
7ce7e424 | 207 | struct ftrace_event_call *call = &event_##call; \ |
c32e827b SR |
208 | struct ring_buffer_event *event; \ |
209 | struct ftrace_raw_##call *entry; \ | |
210 | unsigned long irq_flags; \ | |
211 | int pc; \ | |
212 | \ | |
213 | local_save_flags(irq_flags); \ | |
214 | pc = preempt_count(); \ | |
215 | \ | |
216 | event = trace_current_buffer_lock_reserve(event_##call.id, \ | |
ef18012b | 217 | sizeof(struct ftrace_raw_##call), \ |
c32e827b SR |
218 | irq_flags, pc); \ |
219 | if (!event) \ | |
220 | return; \ | |
221 | entry = ring_buffer_event_data(event); \ | |
222 | \ | |
da4d0302 | 223 | assign; \ |
c32e827b | 224 | \ |
7ce7e424 TZ |
225 | if (call->preds && !filter_match_preds(call, entry)) \ |
226 | ring_buffer_event_discard(event); \ | |
b118415b FW |
227 | \ |
228 | trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \ | |
229 | \ | |
c32e827b SR |
230 | } \ |
231 | \ | |
232 | static int ftrace_raw_reg_event_##call(void) \ | |
233 | { \ | |
234 | int ret; \ | |
235 | \ | |
236 | ret = register_trace_##call(ftrace_raw_event_##call); \ | |
633ddaa7 | 237 | if (ret) \ |
c32e827b | 238 | pr_info("event trace: Could not activate trace point " \ |
633ddaa7 | 239 | "probe to " #call "\n"); \ |
c32e827b SR |
240 | return ret; \ |
241 | } \ | |
242 | \ | |
243 | static void ftrace_raw_unreg_event_##call(void) \ | |
244 | { \ | |
245 | unregister_trace_##call(ftrace_raw_event_##call); \ | |
246 | } \ | |
247 | \ | |
248 | static struct trace_event ftrace_event_type_##call = { \ | |
249 | .trace = ftrace_raw_output_##call, \ | |
250 | }; \ | |
251 | \ | |
252 | static int ftrace_raw_init_event_##call(void) \ | |
253 | { \ | |
254 | int id; \ | |
255 | \ | |
256 | id = register_ftrace_event(&ftrace_event_type_##call); \ | |
257 | if (!id) \ | |
258 | return -ENODEV; \ | |
259 | event_##call.id = id; \ | |
cf027f64 | 260 | INIT_LIST_HEAD(&event_##call.fields); \ |
c32e827b SR |
261 | return 0; \ |
262 | } \ | |
263 | \ | |
264 | static struct ftrace_event_call __used \ | |
265 | __attribute__((__aligned__(4))) \ | |
266 | __attribute__((section("_ftrace_events"))) event_##call = { \ | |
ef18012b | 267 | .name = #call, \ |
9cc26a26 | 268 | .system = __stringify(TRACE_SYSTEM), \ |
c32e827b | 269 | .raw_init = ftrace_raw_init_event_##call, \ |
da4d0302 SR |
270 | .regfunc = ftrace_raw_reg_event_##call, \ |
271 | .unregfunc = ftrace_raw_unreg_event_##call, \ | |
981d081e | 272 | .show_format = ftrace_format_##call, \ |
cf027f64 | 273 | .define_fields = ftrace_define_fields_##call, \ |
ac199db0 | 274 | _TRACE_PROFILE_INIT(call) \ |
c32e827b | 275 | } |
ac199db0 PZ |
276 | |
277 | #include <trace/trace_event_types.h> | |
278 | ||
279 | #undef _TRACE_PROFILE | |
280 | #undef _TRACE_PROFILE_INIT | |
281 |