tracing: add raw trace point recording infrastructure
[linux-2.6] / kernel / trace / trace_events_stage_3.h
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  * {
8  *      event_trace_printk(_RET_IP_, "(<call>) " <fmt>);
9  * }
10  *
11  * static int ftrace_reg_event_<call>(void)
12  * {
13  *      int ret;
14  *
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;
20  * }
21  *
22  * static void ftrace_unreg_event_<call>(void)
23  * {
24  *      unregister_trace_<call>(ftrace_event_<call>);
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> = {
32  *      .name                   = "<call>",
33  *      .regfunc                = ftrace_reg_event_<call>,
34  *      .unregfunc              = ftrace_unreg_event_<call>,
35  * }
36  *
37  *
38  * For those macros defined with TRACE_EVENT_FORMAT:
39  *
40  * static struct ftrace_event_call event_<call>;
41  *
42  * static void ftrace_raw_event_<call>(proto)
43  * {
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  *      <tstruct>;  <-- Here we assign the entries by the TRACE_FIELD.
60  *
61  *      trace_current_buffer_unlock_commit(event, irq_flags, pc);
62  * }
63  *
64  * static int ftrace_raw_reg_event_<call>(void)
65  * {
66  *      int ret;
67  *
68  *      ret = register_trace_<call>(ftrace_raw_event_<call>);
69  *      if (!ret)
70  *              pr_info("event trace: Could not activate trace point "
71  *                      "probe to <call>");
72  *      return ret;
73  * }
74  *
75  * static void ftrace_unreg_event_<call>(void)
76  * {
77  *      unregister_trace_<call>(ftrace_raw_event_<call>);
78  * }
79  *
80  * static struct trace_event ftrace_event_type_<call> = {
81  *      .trace                  = ftrace_raw_output_<call>, <-- stage 2
82  * };
83  *
84  * static int ftrace_raw_init_event_<call>(void)
85  * {
86  *      int id;
87  *
88  *      id = register_ftrace_event(&ftrace_event_type_<call>);
89  *      if (!id)
90  *              return -ENODEV;
91  *      event_<call>.id = id;
92  *      return 0;
93  * }
94  *
95  * static struct ftrace_event_call __used
96  * __attribute__((__aligned__(4)))
97  * __attribute__((section("_ftrace_events"))) event_<call> = {
98  *      .name                   = "<call>",
99  *      .regfunc                = ftrace_reg_event_<call>,
100  *      .unregfunc              = ftrace_unreg_event_<call>,
101  *      .raw_init               = ftrace_raw_init_event_<call>,
102  *      .raw_reg                = ftrace_raw_reg_event_<call>,
103  *      .raw_unreg              = ftrace_raw_unreg_event_<call>,
104  * }
105  *
106  */
107
108 #undef TPFMT
109 #define TPFMT(fmt, args...)     fmt "\n", ##args
110
111 #define _TRACE_FORMAT(call, proto, args, fmt)                           \
112 static void ftrace_event_##call(proto)                                  \
113 {                                                                       \
114         event_trace_printk(_RET_IP_, "(" #call ") " fmt);               \
115 }                                                                       \
116                                                                         \
117 static int ftrace_reg_event_##call(void)                                \
118 {                                                                       \
119         int ret;                                                        \
120                                                                         \
121         ret = register_trace_##call(ftrace_event_##call);               \
122         if (!ret)                                                       \
123                 pr_info("event trace: Could not activate trace point "  \
124                         "probe to " #call);                             \
125         return ret;                                                     \
126 }                                                                       \
127                                                                         \
128 static void ftrace_unreg_event_##call(void)                             \
129 {                                                                       \
130         unregister_trace_##call(ftrace_event_##call);                   \
131 }                                                                       \
132
133
134 #undef TRACE_FORMAT
135 #define TRACE_FORMAT(call, proto, args, fmt)                            \
136 _TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt))           \
137 static struct ftrace_event_call __used                                  \
138 __attribute__((__aligned__(4)))                                         \
139 __attribute__((section("_ftrace_events"))) event_##call = {             \
140         .name                   = #call,                                \
141         .system                 = STR(TRACE_SYSTEM),                    \
142         .regfunc                = ftrace_reg_event_##call,              \
143         .unregfunc              = ftrace_unreg_event_##call,            \
144 }
145
146 #undef TRACE_FIELD
147 #define TRACE_FIELD(type, item, assign)\
148         entry->item = assign;
149
150 #undef TRACE_EVENT_FORMAT
151 #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)      \
152 _TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt))           \
153                                                                         \
154 static struct ftrace_event_call event_##call;                           \
155                                                                         \
156 static void ftrace_raw_event_##call(proto)                              \
157 {                                                                       \
158         struct ring_buffer_event *event;                                \
159         struct ftrace_raw_##call *entry;                                \
160         unsigned long irq_flags;                                        \
161         int pc;                                                         \
162                                                                         \
163         local_save_flags(irq_flags);                                    \
164         pc = preempt_count();                                           \
165                                                                         \
166         event = trace_current_buffer_lock_reserve(event_##call.id,      \
167                                   sizeof(struct ftrace_raw_##call),     \
168                                   irq_flags, pc);                       \
169         if (!event)                                                     \
170                 return;                                                 \
171         entry   = ring_buffer_event_data(event);                        \
172                                                                         \
173         tstruct;                                                        \
174                                                                         \
175         trace_current_buffer_unlock_commit(event, irq_flags, pc);       \
176 }                                                                       \
177                                                                         \
178 static int ftrace_raw_reg_event_##call(void)                            \
179 {                                                                       \
180         int ret;                                                        \
181                                                                         \
182         ret = register_trace_##call(ftrace_raw_event_##call);           \
183         if (!ret)                                                       \
184                 pr_info("event trace: Could not activate trace point "  \
185                         "probe to " #call);                             \
186         return ret;                                                     \
187 }                                                                       \
188                                                                         \
189 static void ftrace_raw_unreg_event_##call(void)                         \
190 {                                                                       \
191         unregister_trace_##call(ftrace_raw_event_##call);               \
192 }                                                                       \
193                                                                         \
194 static struct trace_event ftrace_event_type_##call = {                  \
195         .trace                  = ftrace_raw_output_##call,             \
196 };                                                                      \
197                                                                         \
198 static int ftrace_raw_init_event_##call(void)                           \
199 {                                                                       \
200         int id;                                                         \
201                                                                         \
202         id = register_ftrace_event(&ftrace_event_type_##call);          \
203         if (!id)                                                        \
204                 return -ENODEV;                                         \
205         event_##call.id = id;                                           \
206         return 0;                                                       \
207 }                                                                       \
208                                                                         \
209 static struct ftrace_event_call __used                                  \
210 __attribute__((__aligned__(4)))                                         \
211 __attribute__((section("_ftrace_events"))) event_##call = {             \
212         .name                   = #call,                                \
213         .system                 = STR(TRACE_SYSTEM),                    \
214         .regfunc                = ftrace_reg_event_##call,              \
215         .unregfunc              = ftrace_unreg_event_##call,            \
216         .raw_init               = ftrace_raw_init_event_##call,         \
217         .raw_reg                = ftrace_raw_reg_event_##call,          \
218         .raw_unreg              = ftrace_raw_unreg_event_##call,        \
219 }