Commit | Line | Data |
---|---|---|
40652b65 | 1 | #include <lttng.h> |
299338c8 | 2 | #include <lttng-types.h> |
d0dd2ecb | 3 | #include <linux/debugfs.h> |
b13f3ebe | 4 | #include "../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ |
f3bc08c5 | 5 | #include "../wrapper/ringbuffer/frontend_types.h" |
e763dbf5 | 6 | #include "../ltt-events.h" |
6db3d13b | 7 | #include "../ltt-tracer-core.h" |
40652b65 | 8 | |
299338c8 MD |
9 | struct lttng_event_field { |
10 | const char *name; | |
11 | const struct lttng_type type; | |
12 | }; | |
13 | ||
14 | struct lttng_event_desc { | |
15 | const struct lttng_event_field *fields; | |
d0dd2ecb | 16 | const char *name; |
19c57fbf | 17 | void *probe_callback; |
d0dd2ecb | 18 | unsigned int nr_fields; |
299338c8 | 19 | }; |
40652b65 MD |
20 | |
21 | /* | |
6db3d13b | 22 | * Macro declarations used for all stages. |
40652b65 MD |
23 | */ |
24 | ||
25 | /* | |
26 | * DECLARE_EVENT_CLASS can be used to add a generic function | |
27 | * handlers for events. That is, if all events have the same | |
28 | * parameters and just have distinct trace points. | |
29 | * Each tracepoint can be defined with DEFINE_EVENT and that | |
30 | * will map the DECLARE_EVENT_CLASS to the tracepoint. | |
31 | * | |
32 | * TRACE_EVENT is a one to one mapping between tracepoint and template. | |
33 | */ | |
6db3d13b | 34 | |
40652b65 MD |
35 | #undef TRACE_EVENT |
36 | #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ | |
37 | DECLARE_EVENT_CLASS(name, \ | |
38 | PARAMS(proto), \ | |
39 | PARAMS(args), \ | |
40 | PARAMS(tstruct), \ | |
41 | PARAMS(assign), \ | |
299338c8 MD |
42 | PARAMS(print)) \ |
43 | DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)) | |
40652b65 | 44 | |
6db3d13b MD |
45 | #undef DEFINE_EVENT_PRINT |
46 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | |
47 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | |
48 | ||
49 | /* Callbacks are meaningless to LTTng. */ | |
50 | #undef TRACE_EVENT_FN | |
51 | #define TRACE_EVENT_FN(name, proto, args, tstruct, \ | |
52 | assign, print, reg, unreg) \ | |
53 | TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ | |
54 | PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ | |
55 | ||
56 | /* | |
57 | * Stage 1 of the trace events. | |
58 | * | |
59 | * Create event field type metadata section. | |
60 | * Each event produce an array of fields. | |
61 | */ | |
62 | ||
63 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
64 | ||
1d12cebd MD |
65 | /* Named field types must be defined in lttng-types.h */ |
66 | ||
40652b65 | 67 | #undef __field |
299338c8 MD |
68 | #define __field(_type, _item) \ |
69 | { .name = #_item, .type = { .atype = atype_integer, .name = #_type} }, | |
40652b65 MD |
70 | |
71 | #undef __field_ext | |
6db3d13b | 72 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) |
40652b65 MD |
73 | |
74 | #undef __array | |
299338c8 MD |
75 | #define __array(_type, _item, _length) \ |
76 | { \ | |
77 | .name = #_item, \ | |
78 | .type = { \ | |
79 | .atype = atype_array, \ | |
80 | .name = NULL, \ | |
81 | .u.array.elem_type = #_type, \ | |
82 | .u.array.length = _length, \ | |
83 | }, \ | |
84 | }, | |
40652b65 MD |
85 | |
86 | #undef __dynamic_array | |
299338c8 MD |
87 | #define __dynamic_array(_type, _item, _length) \ |
88 | { \ | |
89 | .name = #_item, \ | |
90 | .type = { \ | |
91 | .atype = atype_sequence, \ | |
92 | .name = NULL, \ | |
93 | .u.sequence.elem_type = #_type, \ | |
94 | .u.sequence.length_type = "u32", \ | |
95 | }, \ | |
96 | }, | |
40652b65 MD |
97 | |
98 | #undef __string | |
1d12cebd | 99 | #define __string(_item, _src) \ |
299338c8 | 100 | { \ |
0d1d4002 | 101 | .name = #_item, \ |
299338c8 MD |
102 | .type = { \ |
103 | .atype = atype_string, \ | |
104 | .name = NULL, \ | |
105 | .u.string.encoding = lttng_encode_UTF8, \ | |
106 | }, \ | |
107 | }, | |
1d12cebd | 108 | |
40652b65 | 109 | #undef TP_STRUCT__entry |
1d12cebd MD |
110 | #define TP_STRUCT__entry(args...) args /* Only one used in this phase */ |
111 | ||
40652b65 | 112 | #undef DECLARE_EVENT_CLASS |
0d1d4002 MD |
113 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ |
114 | static const struct lttng_event_field __event_fields___##_name[] = { \ | |
115 | _tstruct \ | |
299338c8 MD |
116 | }; |
117 | ||
299338c8 MD |
118 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
119 | ||
19c57fbf MD |
120 | /* |
121 | * Stage 1.1 of the trace events. | |
122 | * | |
123 | * Create probe callback prototypes. | |
124 | */ | |
125 | ||
126 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
127 | ||
128 | #undef TP_PROTO | |
129 | #define TP_PROTO(args...) args | |
130 | ||
131 | #undef DECLARE_EVENT_CLASS | |
132 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
133 | static void __event_probe__##_name(void *__data, _proto); | |
134 | ||
135 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
136 | ||
299338c8 MD |
137 | /* |
138 | * Stage 2 of the trace events. | |
139 | * | |
140 | * Create an array of events. | |
141 | */ | |
142 | ||
299338c8 MD |
143 | /* Named field types must be defined in lttng-types.h */ |
144 | ||
6db3d13b | 145 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ |
299338c8 | 146 | |
d32a57a2 MD |
147 | #undef DEFINE_EVENT |
148 | #define DEFINE_EVENT(_template, _name, _proto, _args) \ | |
149 | { \ | |
150 | .fields = __event_fields___##_template, \ | |
151 | .name = #_name, \ | |
19c57fbf | 152 | .probe_callback = (void *) &__event_probe__##_template,\ |
d32a57a2 | 153 | .nr_fields = ARRAY_SIZE(__event_fields___##_template), \ |
6db3d13b | 154 | }, |
40652b65 | 155 | |
d0dd2ecb MD |
156 | #define TP_ID1(_token, _system) _token##_system |
157 | #define TP_ID(_token, _system) TP_ID1(_token, _system) | |
40652b65 | 158 | |
d0dd2ecb | 159 | static const struct lttng_event_desc TP_ID(__event_desc___, TRACE_SYSTEM)[] = { |
40652b65 | 160 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
299338c8 MD |
161 | }; |
162 | ||
d0dd2ecb MD |
163 | #undef TP_ID1 |
164 | #undef TP_ID | |
165 | ||
166 | /* | |
167 | * Stage 3 of the trace events. | |
168 | * | |
169 | * Create seq file metadata output. | |
170 | */ | |
171 | ||
d0dd2ecb MD |
172 | #define TP_ID1(_token, _system) _token##_system |
173 | #define TP_ID(_token, _system) TP_ID1(_token, _system) | |
d0dd2ecb MD |
174 | |
175 | static void *TP_ID(__lttng_seq_start__, TRACE_SYSTEM)(struct seq_file *m, | |
176 | loff_t *pos) | |
177 | { | |
6db3d13b MD |
178 | const struct lttng_event_desc *desc = |
179 | &TP_ID(__event_desc___, TRACE_SYSTEM)[*pos]; | |
d0dd2ecb | 180 | |
6db3d13b MD |
181 | if (desc > &TP_ID(__event_desc___, TRACE_SYSTEM) |
182 | [ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)) - 1]) | |
d0dd2ecb MD |
183 | return NULL; |
184 | return (void *) desc; | |
185 | } | |
186 | ||
187 | static void *TP_ID(__lttng_seq_next__, TRACE_SYSTEM)(struct seq_file *m, | |
188 | void *p, loff_t *ppos) | |
189 | { | |
6db3d13b MD |
190 | const struct lttng_event_desc *desc = |
191 | &TP_ID(__event_desc___, TRACE_SYSTEM)[++(*ppos)]; | |
d0dd2ecb | 192 | |
6db3d13b MD |
193 | if (desc > &TP_ID(__event_desc___, TRACE_SYSTEM) |
194 | [ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)) - 1]) | |
d0dd2ecb MD |
195 | return NULL; |
196 | return (void *) desc; | |
197 | } | |
198 | ||
199 | static void TP_ID(__lttng_seq_stop__, TRACE_SYSTEM)(struct seq_file *m, | |
200 | void *p) | |
201 | { | |
202 | } | |
203 | ||
204 | static int TP_ID(__lttng_seq_show__, TRACE_SYSTEM)(struct seq_file *m, | |
205 | void *p) | |
206 | { | |
207 | const struct lttng_event_desc *desc = p; | |
208 | int i; | |
209 | ||
210 | seq_printf(m, "event {\n" | |
211 | "\tname = %s;\n" | |
212 | "\tid = UNKNOWN;\n" | |
213 | "\tstream = UNKNOWN;\n" | |
214 | "\tfields = {\n", | |
215 | desc->name); | |
216 | for (i = 0; i < desc->nr_fields; i++) { | |
217 | if (desc->fields[i].type.name) /* Named type */ | |
218 | seq_printf(m, "\t\t%s", | |
219 | desc->fields[i].type.name); | |
220 | else /* Nameless type */ | |
221 | lttng_print_event_type(m, 2, &desc->fields[i].type); | |
222 | seq_printf(m, " %s;\n", desc->fields[i].name); | |
223 | } | |
224 | seq_printf(m, "\t};\n"); | |
225 | seq_printf(m, "};\n"); | |
226 | return 0; | |
227 | } | |
228 | ||
229 | static const | |
230 | struct seq_operations TP_ID(__lttng_types_seq_ops__, TRACE_SYSTEM) = { | |
231 | .start = TP_ID(__lttng_seq_start__, TRACE_SYSTEM), | |
232 | .next = TP_ID(__lttng_seq_next__, TRACE_SYSTEM), | |
233 | .stop = TP_ID(__lttng_seq_stop__, TRACE_SYSTEM), | |
234 | .show = TP_ID(__lttng_seq_show__, TRACE_SYSTEM), | |
235 | }; | |
236 | ||
237 | static int | |
238 | TP_ID(__lttng_types_open__, TRACE_SYSTEM)(struct inode *inode, struct file *file) | |
239 | { | |
240 | return seq_open(file, &TP_ID(__lttng_types_seq_ops__, TRACE_SYSTEM)); | |
241 | } | |
242 | ||
6db3d13b MD |
243 | static const |
244 | struct file_operations TP_ID(__lttng_types_fops__, TRACE_SYSTEM) = { | |
d0dd2ecb MD |
245 | .open = TP_ID(__lttng_types_open__, TRACE_SYSTEM), |
246 | .read = seq_read, | |
247 | .llseek = seq_lseek, | |
248 | .release = seq_release_private, | |
249 | }; | |
250 | ||
251 | static struct dentry *TP_ID(__lttng_types_dentry__, TRACE_SYSTEM); | |
252 | ||
253 | static int TP_ID(__lttng_types_init__, TRACE_SYSTEM)(void) | |
254 | { | |
255 | int ret = 0; | |
256 | ||
257 | TP_ID(__lttng_types_dentry__, TRACE_SYSTEM) = | |
6db3d13b MD |
258 | debugfs_create_file("lttng-events-" __stringify(TRACE_SYSTEM), |
259 | S_IWUSR, NULL, NULL, | |
260 | &TP_ID(__lttng_types_fops__, TRACE_SYSTEM)); | |
d0dd2ecb MD |
261 | if (IS_ERR(TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)) |
262 | || !TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)) { | |
263 | printk(KERN_ERR "Error creating LTTng type export file\n"); | |
264 | ret = -ENOMEM; | |
265 | goto error; | |
266 | } | |
267 | error: | |
268 | return ret; | |
269 | } | |
270 | ||
d0dd2ecb MD |
271 | static void TP_ID(__lttng_types_exit__, TRACE_SYSTEM)(void) |
272 | { | |
273 | debugfs_remove(TP_ID(__lttng_types_dentry__, TRACE_SYSTEM)); | |
274 | } | |
275 | ||
d0dd2ecb MD |
276 | #undef TP_ID1 |
277 | #undef TP_ID | |
278 | ||
40652b65 | 279 | /* |
6db3d13b | 280 | * Stage 4 of the trace events. |
40652b65 MD |
281 | * |
282 | * Create static inline function that calculates event size. | |
283 | */ | |
284 | ||
6db3d13b | 285 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ |
40652b65 | 286 | |
6db3d13b MD |
287 | /* Named field types must be defined in lttng-types.h */ |
288 | ||
289 | #undef __field | |
85a80742 MD |
290 | #define __field(_type, _item) \ |
291 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \ | |
0d1d4002 | 292 | __event_len += sizeof(_type); |
6db3d13b MD |
293 | |
294 | #undef __field_ext | |
295 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
296 | ||
297 | #undef __array | |
85a80742 MD |
298 | #define __array(_type, _item, _length) \ |
299 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \ | |
0d1d4002 | 300 | __event_len += sizeof(_type) * (_length); |
6db3d13b MD |
301 | |
302 | #undef __dynamic_array | |
85a80742 MD |
303 | #define __dynamic_array(_type, _item, _length) \ |
304 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(u32)); \ | |
305 | __event_len += sizeof(u32); \ | |
306 | __event_len += lib_ring_buffer_align(__event_len, __alignof__(_type)); \ | |
0d1d4002 | 307 | __event_len += sizeof(_type) * (_length); |
6db3d13b MD |
308 | |
309 | #undef __string | |
85a80742 | 310 | #define __string(_item, _src) \ |
0d1d4002 MD |
311 | __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; |
312 | ||
313 | #undef TP_PROTO | |
314 | #define TP_PROTO(args...) args | |
6db3d13b MD |
315 | |
316 | #undef TP_STRUCT__entry | |
0d1d4002 | 317 | #define TP_STRUCT__entry(args...) args |
6db3d13b MD |
318 | |
319 | #undef DECLARE_EVENT_CLASS | |
0d1d4002 MD |
320 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ |
321 | static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ | |
322 | { \ | |
323 | size_t __event_len = 0; \ | |
324 | unsigned int __dynamic_len_idx = 0; \ | |
325 | \ | |
326 | if (0) \ | |
327 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
328 | _tstruct \ | |
329 | return __event_len; \ | |
6db3d13b | 330 | } |
40652b65 MD |
331 | |
332 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
333 | ||
6db3d13b | 334 | |
6db3d13b | 335 | |
40652b65 | 336 | /* |
e763dbf5 MD |
337 | * Stage 5 of the trace events. |
338 | * | |
339 | * Create static inline function that calculates event payload alignment. | |
340 | */ | |
341 | ||
342 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
343 | ||
344 | /* Named field types must be defined in lttng-types.h */ | |
345 | ||
346 | #undef __field | |
347 | #define __field(_type, _item) \ | |
67e5e60c | 348 | __event_align = max_t(size_t, __event_align, __alignof__(_type)); |
e763dbf5 MD |
349 | |
350 | #undef __field_ext | |
351 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
352 | ||
353 | #undef __array | |
354 | #define __array(_type, _item, _length) \ | |
67e5e60c | 355 | __event_align = max_t(size_t, __event_align, __alignof__(_type)); |
e763dbf5 MD |
356 | |
357 | #undef __dynamic_array | |
358 | #define __dynamic_array(_type, _item, _length) \ | |
67e5e60c MD |
359 | __event_align = max_t(size_t, __event_align, __alignof__(u32)); \ |
360 | __event_align = max_t(size_t, __event_align, __alignof__(_type)); | |
e763dbf5 MD |
361 | |
362 | #undef __string | |
363 | #define __string(_item, _src) | |
364 | ||
365 | #undef TP_PROTO | |
366 | #define TP_PROTO(args...) args | |
367 | ||
368 | #undef TP_STRUCT__entry | |
369 | #define TP_STRUCT__entry(args...) args | |
370 | ||
371 | #undef DECLARE_EVENT_CLASS | |
372 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
373 | static inline size_t __event_get_align__##_name(_proto) \ | |
374 | { \ | |
375 | size_t __event_align = 1; \ | |
376 | _tstruct \ | |
377 | return __event_align; \ | |
378 | } | |
379 | ||
380 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
381 | ||
382 | ||
e763dbf5 MD |
383 | /* |
384 | * Stage 6 of the trace events. | |
40652b65 | 385 | * |
3c4ffab9 MD |
386 | * Create structure declaration that allows the "assign" macros to access the |
387 | * field types. | |
388 | */ | |
389 | ||
390 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
391 | ||
392 | /* Named field types must be defined in lttng-types.h */ | |
393 | ||
394 | #undef __field | |
395 | #define __field(_type, _item) _type _item; | |
396 | ||
397 | #undef __field_ext | |
398 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
399 | ||
400 | #undef __array | |
401 | #define __array(_type, _item, _length) _type _item; | |
402 | ||
403 | #undef __dynamic_array | |
404 | #define __dynamic_array(_type, _item, _length) _type _item; | |
405 | ||
406 | #undef __string | |
407 | #define __string(_item, _src) char _item; | |
408 | ||
409 | #undef TP_STRUCT__entry | |
410 | #define TP_STRUCT__entry(args...) args | |
411 | ||
412 | #undef DECLARE_EVENT_CLASS | |
413 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
414 | struct __event_typemap__##_name { \ | |
415 | _tstruct \ | |
416 | }; | |
417 | ||
418 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
419 | ||
420 | ||
421 | /* | |
422 | * Stage 7 of the trace events. | |
423 | * | |
40652b65 MD |
424 | * Create the probe function : call even size calculation and write event data |
425 | * into the buffer. | |
e763dbf5 | 426 | * |
67e5e60c MD |
427 | * We use both the field and assignment macros to write the fields in the order |
428 | * defined in the field declaration. The field declarations control the | |
429 | * execution order, jumping to the appropriate assignment block. | |
40652b65 MD |
430 | */ |
431 | ||
e763dbf5 MD |
432 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ |
433 | ||
434 | #undef __field | |
435 | #define __field(_type, _item) \ | |
e763dbf5 MD |
436 | goto __assign_##_item; \ |
437 | __end_field_##_item: | |
40652b65 | 438 | |
e763dbf5 MD |
439 | #undef __field_ext |
440 | #define __field_ext(_type, _item, _filter_type) __field(_type, _item) | |
40652b65 | 441 | |
e763dbf5 MD |
442 | #undef __array |
443 | #define __array(_type, _item, _length) \ | |
e763dbf5 MD |
444 | goto __assign_##_item; \ |
445 | __end_field_##_item: | |
40652b65 | 446 | |
e763dbf5 MD |
447 | #undef __dynamic_array |
448 | #define __dynamic_array(_type, _item, _length) \ | |
e763dbf5 MD |
449 | goto __assign_##_item##_1; \ |
450 | __end_field_##_item##_1: \ | |
e763dbf5 MD |
451 | goto __assign_##_item##_2; \ |
452 | __end_field_##_item##_2: | |
40652b65 | 453 | |
e763dbf5 MD |
454 | #undef __string |
455 | #define __string(_item, _src) \ | |
456 | goto __assign_##_item; \ | |
457 | __end_field_##_item: | |
458 | ||
459 | /* | |
460 | * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() to | |
461 | * strcpy(). | |
462 | */ | |
463 | #undef tp_assign | |
464 | #define tp_assign(dest, src) \ | |
465 | __assign_##dest: \ | |
466 | { \ | |
3c4ffab9 MD |
467 | __typeof__(__typemap.dest) __tmp = (src); \ |
468 | lib_ring_buffer_align_ctx(&ctx, __alignof__(__tmp)); \ | |
469 | __chan->ops->event_write(&ctx, &__tmp, sizeof(__tmp)); \ | |
e763dbf5 MD |
470 | } \ |
471 | goto __end_field_##dest; | |
472 | ||
473 | #undef tp_memcpy | |
474 | #define tp_memcpy(dest, src, len) \ | |
475 | __assign_##dest: \ | |
3c4ffab9 | 476 | lib_ring_buffer_align_ctx(&ctx, __alignof__(__typemap.dest)); \ |
e763dbf5 MD |
477 | __chan->ops->event_write(&ctx, src, len); \ |
478 | goto __end_field_##dest; | |
479 | ||
480 | #undef tp_memcpy_dyn | |
481 | #define tp_memcpy_dyn(dest, src, len) \ | |
482 | __assign_##dest##_1: \ | |
483 | { \ | |
3c4ffab9 MD |
484 | u32 __tmpl = (len); \ |
485 | lib_ring_buffer_align_ctx(&ctx, __alignof__(u32)); \ | |
e763dbf5 MD |
486 | __chan->ops->event_write(&ctx, &__tmpl, sizeof(u32)); \ |
487 | } \ | |
488 | goto __end_field_##dest##_1; \ | |
489 | __assign_##dest##_2: \ | |
3c4ffab9 | 490 | lib_ring_buffer_align_ctx(&ctx, __alignof__(__typemap.dest)); \ |
e763dbf5 MD |
491 | __chan->ops->event_write(&ctx, src, len); \ |
492 | goto __end_field_##dest##_2; | |
493 | ||
494 | #undef tp_strcpy | |
495 | #define tp_strcpy(dest, src) \ | |
3c4ffab9 | 496 | tp_memcpy(dest, src, __get_dynamic_array_len(dest)) |
40652b65 | 497 | |
e763dbf5 MD |
498 | /* Named field types must be defined in lttng-types.h */ |
499 | ||
500 | #undef __get_str | |
501 | #define __get_str(field) field | |
502 | ||
503 | #undef __get_dynamic_array | |
504 | #define __get_dynamic_array(field) field | |
505 | ||
506 | /* Beware: this get len actually consumes the len value */ | |
507 | #undef __get_dynamic_array_len | |
508 | #define __get_dynamic_array_len(field) __dynamic_len[__dynamic_len_idx++] | |
509 | ||
510 | #undef TP_PROTO | |
511 | #define TP_PROTO(args...) args | |
512 | ||
513 | #undef TP_ARGS | |
514 | #define TP_ARGS(args...) args | |
515 | ||
516 | #undef TP_STRUCT__entry | |
517 | #define TP_STRUCT__entry(args...) args | |
518 | ||
519 | #undef TP_fast_assign | |
520 | #define TP_fast_assign(args...) args | |
521 | ||
522 | #undef DECLARE_EVENT_CLASS | |
523 | #define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ | |
524 | static void __event_probe__##_name(void *__data, _proto) \ | |
525 | { \ | |
526 | struct ltt_event *__event = __data; \ | |
527 | struct ltt_channel *__chan = __event->chan; \ | |
528 | struct lib_ring_buffer_ctx ctx; \ | |
529 | size_t __event_len, __event_align; \ | |
530 | size_t __dynamic_len_idx = 0; \ | |
531 | size_t __dynamic_len[ARRAY_SIZE(__event_fields___##_name)]; \ | |
3c4ffab9 | 532 | struct __event_typemap__##_name __typemap; \ |
e763dbf5 MD |
533 | int __ret; \ |
534 | \ | |
535 | if (0) \ | |
536 | (void) __dynamic_len_idx; /* don't warn if unused */ \ | |
52fc2e1f MD |
537 | if (!ACCESS_ONCE(__chan->session->active)) \ |
538 | return; \ | |
e763dbf5 MD |
539 | __event_len = __event_get_size__##_name(__dynamic_len, _args); \ |
540 | __event_align = __event_get_align__##_name(_args); \ | |
541 | lib_ring_buffer_ctx_init(&ctx, __chan->chan, NULL, __event_len, \ | |
542 | __event_align, -1); \ | |
543 | __ret = __chan->ops->event_reserve(&ctx); \ | |
544 | if (__ret < 0) \ | |
545 | return; \ | |
546 | /* Control code (field ordering) */ \ | |
547 | _tstruct \ | |
548 | __chan->ops->event_commit(&ctx); \ | |
549 | return; \ | |
550 | /* Copy code, steered by control code */ \ | |
551 | _assign \ | |
552 | } | |
553 | ||
554 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | |
555 | ||
3afe7aac MD |
556 | /* |
557 | * Stage 8 of the trace events. | |
558 | * | |
559 | * Register/unregister probes at module load/unload. | |
560 | */ | |
561 | ||
562 | #include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ | |
563 | ||
564 | #define TP_ID1(_token, _system) _token##_system | |
565 | #define TP_ID(_token, _system) TP_ID1(_token, _system) | |
566 | #define module_init_eval1(_token, _system) module_init(_token##_system) | |
567 | #define module_init_eval(_token, _system) module_init_eval1(_token, _system) | |
568 | #define module_exit_eval1(_token, _system) module_exit(_token##_system) | |
569 | #define module_exit_eval(_token, _system) module_exit_eval1(_token, _system) | |
570 | ||
3afe7aac MD |
571 | static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void) |
572 | { | |
19c57fbf MD |
573 | int ret; |
574 | int i; | |
3afe7aac | 575 | |
6d2a620c | 576 | wrapper_vmalloc_sync_all(); |
3afe7aac MD |
577 | ret = TP_ID(__lttng_types_init__, TRACE_SYSTEM)(); |
578 | if (ret) | |
579 | return ret; | |
19c57fbf MD |
580 | for (i = 0; i < ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)); i++) { |
581 | const struct lttng_event_desc *event_desc; | |
582 | ||
583 | event_desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[i]; | |
584 | ret = ltt_probe_register(event_desc->name, | |
585 | event_desc->probe_callback); | |
586 | if (ret) | |
587 | goto error; | |
588 | } | |
589 | return 0; | |
590 | ||
591 | error: | |
592 | for (i--; i >= 0; i--) { | |
593 | const struct lttng_event_desc *event_desc; | |
594 | ||
595 | event_desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[i]; | |
596 | ltt_probe_unregister(event_desc->name); | |
597 | } | |
3afe7aac MD |
598 | return ret; |
599 | } | |
600 | ||
601 | module_init_eval(__lttng_events_init__, TRACE_SYSTEM); | |
602 | ||
3afe7aac MD |
603 | static void TP_ID(__lttng_events_exit__, TRACE_SYSTEM)(void) |
604 | { | |
19c57fbf MD |
605 | int i; |
606 | ||
607 | for (i = 0; i < ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)); i++) { | |
608 | const struct lttng_event_desc *event_desc; | |
609 | ||
610 | event_desc = &TP_ID(__event_desc___, TRACE_SYSTEM)[i]; | |
611 | ltt_probe_unregister(event_desc->name); | |
612 | } | |
3afe7aac MD |
613 | TP_ID(__lttng_types_exit__, TRACE_SYSTEM)(); |
614 | } | |
615 | ||
616 | module_exit_eval(__lttng_events_exit__, TRACE_SYSTEM); | |
617 | ||
618 | #undef module_init_eval | |
619 | #undef module_exit_eval | |
620 | #undef TP_ID1 | |
621 | #undef TP_ID |