Merge branch 'linus' into tracing/core
[linux-2.6] / include / trace / ftrace.h
1 /*
2  * Stage 1 of the trace events.
3  *
4  * Override the macros in <trace/trace_events.h> to include the following:
5  *
6  * struct ftrace_raw_<call> {
7  *      struct trace_entry              ent;
8  *      <type>                          <item>;
9  *      <type2>                         <item2>[<len>];
10  *      [...]
11  * };
12  *
13  * The <type> <item> is created by the __field(type, item) macro or
14  * the __array(type2, item2, len) macro.
15  * We simply do "type item;", and that will create the fields
16  * in the structure.
17  */
18
19 #include <linux/ftrace_event.h>
20
21 #undef __array
22 #define __array(type, item, len)        type    item[len];
23
24 #undef __field
25 #define __field(type, item)             type    item;
26
27 #undef __string
28 #define __string(item, src)             int     __str_loc_##item;
29
30 #undef TP_STRUCT__entry
31 #define TP_STRUCT__entry(args...) args
32
33 #undef TRACE_EVENT
34 #define TRACE_EVENT(name, proto, args, tstruct, assign, print)  \
35         struct ftrace_raw_##name {                              \
36                 struct trace_entry      ent;                    \
37                 tstruct                                         \
38                 char                    __str_data[0];          \
39         };                                                      \
40         static struct ftrace_event_call event_##name
41
42 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
43
44
45 /*
46  * Stage 2 of the trace events.
47  *
48  * Include the following:
49  *
50  * struct ftrace_str_offsets_<call> {
51  *      int                             <str1>;
52  *      int                             <str2>;
53  *      [...]
54  * };
55  *
56  * The __string() macro will create each int <str>, this is to
57  * keep the offset of each string from the beggining of the event
58  * once we perform the strlen() of the src strings.
59  *
60  */
61
62 #undef __array
63 #define __array(type, item, len)
64
65 #undef __field
66 #define __field(type, item);
67
68 #undef __string
69 #define __string(item, src)     int item;
70
71 #undef TRACE_EVENT
72 #define TRACE_EVENT(call, proto, args, tstruct, assign, print)          \
73         struct ftrace_str_offsets_##call {                              \
74                 tstruct;                                                \
75         };
76
77 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
78
79 /*
80  * Stage 3 of the trace events.
81  *
82  * Override the macros in <trace/trace_events.h> to include the following:
83  *
84  * enum print_line_t
85  * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags)
86  * {
87  *      struct trace_seq *s = &iter->seq;
88  *      struct ftrace_raw_<call> *field; <-- defined in stage 1
89  *      struct trace_entry *entry;
90  *      int ret;
91  *
92  *      entry = iter->ent;
93  *
94  *      if (entry->type != event_<call>.id) {
95  *              WARN_ON_ONCE(1);
96  *              return TRACE_TYPE_UNHANDLED;
97  *      }
98  *
99  *      field = (typeof(field))entry;
100  *
101  *      ret = trace_seq_printf(s, <TP_printk> "\n");
102  *      if (!ret)
103  *              return TRACE_TYPE_PARTIAL_LINE;
104  *
105  *      return TRACE_TYPE_HANDLED;
106  * }
107  *
108  * This is the method used to print the raw event to the trace
109  * output format. Note, this is not needed if the data is read
110  * in binary.
111  */
112
113 #undef __entry
114 #define __entry field
115
116 #undef TP_printk
117 #define TP_printk(fmt, args...) fmt "\n", args
118
119 #undef __get_str
120 #define __get_str(field)        ((char *)__entry + __entry->__str_loc_##field)
121
122 #undef TRACE_EVENT
123 #define TRACE_EVENT(call, proto, args, tstruct, assign, print)          \
124 enum print_line_t                                                       \
125 ftrace_raw_output_##call(struct trace_iterator *iter, int flags)        \
126 {                                                                       \
127         struct trace_seq *s = &iter->seq;                               \
128         struct ftrace_raw_##call *field;                                \
129         struct trace_entry *entry;                                      \
130         int ret;                                                        \
131                                                                         \
132         entry = iter->ent;                                              \
133                                                                         \
134         if (entry->type != event_##call.id) {                           \
135                 WARN_ON_ONCE(1);                                        \
136                 return TRACE_TYPE_UNHANDLED;                            \
137         }                                                               \
138                                                                         \
139         field = (typeof(field))entry;                                   \
140                                                                         \
141         ret = trace_seq_printf(s, #call ": " print);                    \
142         if (!ret)                                                       \
143                 return TRACE_TYPE_PARTIAL_LINE;                         \
144                                                                         \
145         return TRACE_TYPE_HANDLED;                                      \
146 }
147         
148 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
149
150 /*
151  * Setup the showing format of trace point.
152  *
153  * int
154  * ftrace_format_##call(struct trace_seq *s)
155  * {
156  *      struct ftrace_raw_##call field;
157  *      int ret;
158  *
159  *      ret = trace_seq_printf(s, #type " " #item ";"
160  *                             " offset:%u; size:%u;\n",
161  *                             offsetof(struct ftrace_raw_##call, item),
162  *                             sizeof(field.type));
163  *
164  * }
165  */
166
167 #undef TP_STRUCT__entry
168 #define TP_STRUCT__entry(args...) args
169
170 #undef __field
171 #define __field(type, item)                                     \
172         ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"      \
173                                "offset:%u;\tsize:%u;\n",                \
174                                (unsigned int)offsetof(typeof(field), item), \
175                                (unsigned int)sizeof(field.item));       \
176         if (!ret)                                                       \
177                 return 0;
178
179 #undef __array
180 #define __array(type, item, len)                                                \
181         ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t"    \
182                                "offset:%u;\tsize:%u;\n",                \
183                                (unsigned int)offsetof(typeof(field), item), \
184                                (unsigned int)sizeof(field.item));       \
185         if (!ret)                                                       \
186                 return 0;
187
188 #undef __string
189 #define __string(item, src)                                                    \
190         ret = trace_seq_printf(s, "\tfield: __str_loc " #item ";\t"            \
191                                "offset:%u;tsize:%u;\n",                        \
192                                (unsigned int)offsetof(typeof(field),           \
193                                         __str_loc_##item),                     \
194                                (unsigned int)sizeof(field.__str_loc_##item));  \
195         if (!ret)                                                              \
196                 return 0;
197
198 #undef __entry
199 #define __entry REC
200
201 #undef TP_printk
202 #define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
203
204 #undef TP_fast_assign
205 #define TP_fast_assign(args...) args
206
207 #undef TRACE_EVENT
208 #define TRACE_EVENT(call, proto, args, tstruct, func, print)            \
209 static int                                                              \
210 ftrace_format_##call(struct trace_seq *s)                               \
211 {                                                                       \
212         struct ftrace_raw_##call field __attribute__((unused));         \
213         int ret = 0;                                                    \
214                                                                         \
215         tstruct;                                                        \
216                                                                         \
217         trace_seq_printf(s, "\nprint fmt: " print);                     \
218                                                                         \
219         return ret;                                                     \
220 }
221
222 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
223
224 #undef __field
225 #define __field(type, item)                                             \
226         ret = trace_define_field(event_call, #type, #item,              \
227                                  offsetof(typeof(field), item),         \
228                                  sizeof(field.item), is_signed_type(type));     \
229         if (ret)                                                        \
230                 return ret;
231
232 #undef __array
233 #define __array(type, item, len)                                        \
234         BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);                         \
235         ret = trace_define_field(event_call, #type "[" #len "]", #item, \
236                                  offsetof(typeof(field), item),         \
237                                  sizeof(field.item), 0);                \
238         if (ret)                                                        \
239                 return ret;
240
241 #undef __string
242 #define __string(item, src)                                                    \
243         ret = trace_define_field(event_call, "__str_loc", #item,               \
244                                 offsetof(typeof(field), __str_loc_##item),     \
245                                  sizeof(field.__str_loc_##item), 0);
246
247 #undef TRACE_EVENT
248 #define TRACE_EVENT(call, proto, args, tstruct, func, print)            \
249 int                                                                     \
250 ftrace_define_fields_##call(void)                                       \
251 {                                                                       \
252         struct ftrace_raw_##call field;                                 \
253         struct ftrace_event_call *event_call = &event_##call;           \
254         int ret;                                                        \
255                                                                         \
256         __common_field(int, type, 1);                                   \
257         __common_field(unsigned char, flags, 0);                        \
258         __common_field(unsigned char, preempt_count, 0);                \
259         __common_field(int, pid, 1);                                    \
260         __common_field(int, tgid, 1);                                   \
261                                                                         \
262         tstruct;                                                        \
263                                                                         \
264         return ret;                                                     \
265 }
266
267 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
268
269 /*
270  * Stage 4 of the trace events.
271  *
272  * Override the macros in <trace/trace_events.h> to include the following:
273  *
274  * static void ftrace_event_<call>(proto)
275  * {
276  *      event_trace_printk(_RET_IP_, "<call>: " <fmt>);
277  * }
278  *
279  * static int ftrace_reg_event_<call>(void)
280  * {
281  *      int ret;
282  *
283  *      ret = register_trace_<call>(ftrace_event_<call>);
284  *      if (!ret)
285  *              pr_info("event trace: Could not activate trace point "
286  *                      "probe to  <call>");
287  *      return ret;
288  * }
289  *
290  * static void ftrace_unreg_event_<call>(void)
291  * {
292  *      unregister_trace_<call>(ftrace_event_<call>);
293  * }
294  *
295  *
296  * For those macros defined with TRACE_EVENT:
297  *
298  * static struct ftrace_event_call event_<call>;
299  *
300  * static void ftrace_raw_event_<call>(proto)
301  * {
302  *      struct ring_buffer_event *event;
303  *      struct ftrace_raw_<call> *entry; <-- defined in stage 1
304  *      unsigned long irq_flags;
305  *      int pc;
306  *
307  *      local_save_flags(irq_flags);
308  *      pc = preempt_count();
309  *
310  *      event = trace_current_buffer_lock_reserve(event_<call>.id,
311  *                                sizeof(struct ftrace_raw_<call>),
312  *                                irq_flags, pc);
313  *      if (!event)
314  *              return;
315  *      entry   = ring_buffer_event_data(event);
316  *
317  *      <assign>;  <-- Here we assign the entries by the __field and
318  *                      __array macros.
319  *
320  *      trace_current_buffer_unlock_commit(event, irq_flags, pc);
321  * }
322  *
323  * static int ftrace_raw_reg_event_<call>(void)
324  * {
325  *      int ret;
326  *
327  *      ret = register_trace_<call>(ftrace_raw_event_<call>);
328  *      if (!ret)
329  *              pr_info("event trace: Could not activate trace point "
330  *                      "probe to <call>");
331  *      return ret;
332  * }
333  *
334  * static void ftrace_unreg_event_<call>(void)
335  * {
336  *      unregister_trace_<call>(ftrace_raw_event_<call>);
337  * }
338  *
339  * static struct trace_event ftrace_event_type_<call> = {
340  *      .trace                  = ftrace_raw_output_<call>, <-- stage 2
341  * };
342  *
343  * static int ftrace_raw_init_event_<call>(void)
344  * {
345  *      int id;
346  *
347  *      id = register_ftrace_event(&ftrace_event_type_<call>);
348  *      if (!id)
349  *              return -ENODEV;
350  *      event_<call>.id = id;
351  *      return 0;
352  * }
353  *
354  * static struct ftrace_event_call __used
355  * __attribute__((__aligned__(4)))
356  * __attribute__((section("_ftrace_events"))) event_<call> = {
357  *      .name                   = "<call>",
358  *      .system                 = "<system>",
359  *      .raw_init               = ftrace_raw_init_event_<call>,
360  *      .regfunc                = ftrace_reg_event_<call>,
361  *      .unregfunc              = ftrace_unreg_event_<call>,
362  *      .show_format            = ftrace_format_<call>,
363  * }
364  *
365  */
366
367 #undef TP_FMT
368 #define TP_FMT(fmt, args...)    fmt "\n", ##args
369
370 #ifdef CONFIG_EVENT_PROFILE
371 #define _TRACE_PROFILE(call, proto, args)                               \
372 static void ftrace_profile_##call(proto)                                \
373 {                                                                       \
374         extern void perf_tpcounter_event(int);                          \
375         perf_tpcounter_event(event_##call.id);                          \
376 }                                                                       \
377                                                                         \
378 static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \
379 {                                                                       \
380         int ret = 0;                                                    \
381                                                                         \
382         if (!atomic_inc_return(&call->profile_count))                   \
383                 ret = register_trace_##call(ftrace_profile_##call);     \
384                                                                         \
385         return ret;                                                     \
386 }                                                                       \
387                                                                         \
388 static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \
389 {                                                                       \
390         if (atomic_add_negative(-1, &call->profile_count))              \
391                 unregister_trace_##call(ftrace_profile_##call);         \
392 }
393
394 #define _TRACE_PROFILE_INIT(call)                                       \
395         .profile_count = ATOMIC_INIT(-1),                               \
396         .profile_enable = ftrace_profile_enable_##call,                 \
397         .profile_disable = ftrace_profile_disable_##call,
398
399 #else
400 #define _TRACE_PROFILE(call, proto, args)
401 #define _TRACE_PROFILE_INIT(call)
402 #endif
403
404 #undef __entry
405 #define __entry entry
406
407 #undef __field
408 #define __field(type, item)
409
410 #undef __array
411 #define __array(type, item, len)
412
413 #undef __string
414 #define __string(item, src)                                                    \
415         __str_offsets.item = __str_size +                                      \
416                              offsetof(typeof(*entry), __str_data);             \
417         __str_size += strlen(src) + 1;
418
419 #undef __assign_str
420 #define __assign_str(dst, src)                                          \
421         __entry->__str_loc_##dst = __str_offsets.dst;                   \
422         strcpy(__get_str(dst), src);
423
424 #undef TRACE_EVENT
425 #define TRACE_EVENT(call, proto, args, tstruct, assign, print)          \
426 _TRACE_PROFILE(call, PARAMS(proto), PARAMS(args))                       \
427                                                                         \
428 static struct ftrace_event_call event_##call;                           \
429                                                                         \
430 static void ftrace_raw_event_##call(proto)                              \
431 {                                                                       \
432         struct ftrace_str_offsets_##call __maybe_unused __str_offsets;  \
433         struct ftrace_event_call *call = &event_##call;                 \
434         struct ring_buffer_event *event;                                \
435         struct ftrace_raw_##call *entry;                                \
436         unsigned long irq_flags;                                        \
437         int __str_size = 0;                                             \
438         int pc;                                                         \
439                                                                         \
440         local_save_flags(irq_flags);                                    \
441         pc = preempt_count();                                           \
442                                                                         \
443         tstruct;                                                        \
444                                                                         \
445         event = trace_current_buffer_lock_reserve(event_##call.id,      \
446                                  sizeof(struct ftrace_raw_##call) + __str_size,\
447                                  irq_flags, pc);                        \
448         if (!event)                                                     \
449                 return;                                                 \
450         entry   = ring_buffer_event_data(event);                        \
451                                                                         \
452         assign;                                                         \
453                                                                         \
454         if (!filter_current_check_discard(call, entry, event))          \
455                 trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \
456 }                                                                       \
457                                                                         \
458 static int ftrace_raw_reg_event_##call(void)                            \
459 {                                                                       \
460         int ret;                                                        \
461                                                                         \
462         ret = register_trace_##call(ftrace_raw_event_##call);           \
463         if (ret)                                                        \
464                 pr_info("event trace: Could not activate trace point "  \
465                         "probe to " #call "\n");                        \
466         return ret;                                                     \
467 }                                                                       \
468                                                                         \
469 static void ftrace_raw_unreg_event_##call(void)                         \
470 {                                                                       \
471         unregister_trace_##call(ftrace_raw_event_##call);               \
472 }                                                                       \
473                                                                         \
474 static struct trace_event ftrace_event_type_##call = {                  \
475         .trace                  = ftrace_raw_output_##call,             \
476 };                                                                      \
477                                                                         \
478 static int ftrace_raw_init_event_##call(void)                           \
479 {                                                                       \
480         int id;                                                         \
481                                                                         \
482         id = register_ftrace_event(&ftrace_event_type_##call);          \
483         if (!id)                                                        \
484                 return -ENODEV;                                         \
485         event_##call.id = id;                                           \
486         INIT_LIST_HEAD(&event_##call.fields);                           \
487         init_preds(&event_##call);                                      \
488         return 0;                                                       \
489 }                                                                       \
490                                                                         \
491 static struct ftrace_event_call __used                                  \
492 __attribute__((__aligned__(4)))                                         \
493 __attribute__((section("_ftrace_events"))) event_##call = {             \
494         .name                   = #call,                                \
495         .system                 = __stringify(TRACE_SYSTEM),            \
496         .event                  = &ftrace_event_type_##call,            \
497         .raw_init               = ftrace_raw_init_event_##call,         \
498         .regfunc                = ftrace_raw_reg_event_##call,          \
499         .unregfunc              = ftrace_raw_unreg_event_##call,        \
500         .show_format            = ftrace_format_##call,                 \
501         .define_fields          = ftrace_define_fields_##call,          \
502         _TRACE_PROFILE_INIT(call)                                       \
503 }
504
505 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
506
507 #undef _TRACE_PROFILE
508 #undef _TRACE_PROFILE_INIT
509