]>
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 | * { | |
efed792d | 8 | * event_trace_printk(_RET_IP_, "<call>: " <fmt>); |
c32e827b SR |
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>, | |
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 SR |
111 | |
112 | #define _TRACE_FORMAT(call, proto, args, fmt) \ | |
113 | static void ftrace_event_##call(proto) \ | |
114 | { \ | |
efed792d | 115 | event_trace_printk(_RET_IP_, #call ": " fmt); \ |
c32e827b SR |
116 | } \ |
117 | \ | |
118 | static int ftrace_reg_event_##call(void) \ | |
119 | { \ | |
120 | int ret; \ | |
121 | \ | |
122 | ret = register_trace_##call(ftrace_event_##call); \ | |
633ddaa7 | 123 | if (ret) \ |
c32e827b | 124 | pr_info("event trace: Could not activate trace point " \ |
633ddaa7 | 125 | "probe to " #call "\n"); \ |
c32e827b SR |
126 | return ret; \ |
127 | } \ | |
128 | \ | |
129 | static void ftrace_unreg_event_##call(void) \ | |
130 | { \ | |
131 | unregister_trace_##call(ftrace_event_##call); \ | |
132 | } \ | |
133 | ||
134 | ||
135 | #undef TRACE_FORMAT | |
136 | #define TRACE_FORMAT(call, proto, args, fmt) \ | |
137 | _TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \ | |
138 | static struct ftrace_event_call __used \ | |
139 | __attribute__((__aligned__(4))) \ | |
140 | __attribute__((section("_ftrace_events"))) event_##call = { \ | |
141 | .name = #call, \ | |
9cc26a26 | 142 | .system = __stringify(TRACE_SYSTEM), \ |
c32e827b SR |
143 | .regfunc = ftrace_reg_event_##call, \ |
144 | .unregfunc = ftrace_unreg_event_##call, \ | |
145 | } | |
146 | ||
147 | #undef TRACE_FIELD | |
148 | #define TRACE_FIELD(type, item, assign)\ | |
149 | entry->item = assign; | |
150 | ||
d20e3b03 SR |
151 | #undef TRACE_FIELD |
152 | #define TRACE_FIELD(type, item, assign)\ | |
153 | entry->item = assign; | |
154 | ||
2939b046 SR |
155 | #undef TP_CMD |
156 | #define TP_CMD(cmd...) cmd | |
d20e3b03 SR |
157 | |
158 | #undef TRACE_ENTRY | |
159 | #define TRACE_ENTRY entry | |
160 | ||
161 | #undef TRACE_FIELD_SPECIAL | |
162 | #define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ | |
163 | cmd; | |
164 | ||
c32e827b SR |
165 | #undef TRACE_EVENT_FORMAT |
166 | #define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ | |
167 | _TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \ | |
168 | \ | |
169 | static struct ftrace_event_call event_##call; \ | |
170 | \ | |
171 | static void ftrace_raw_event_##call(proto) \ | |
172 | { \ | |
173 | struct ring_buffer_event *event; \ | |
174 | struct ftrace_raw_##call *entry; \ | |
175 | unsigned long irq_flags; \ | |
176 | int pc; \ | |
177 | \ | |
178 | local_save_flags(irq_flags); \ | |
179 | pc = preempt_count(); \ | |
180 | \ | |
181 | event = trace_current_buffer_lock_reserve(event_##call.id, \ | |
182 | sizeof(struct ftrace_raw_##call), \ | |
183 | irq_flags, pc); \ | |
184 | if (!event) \ | |
185 | return; \ | |
186 | entry = ring_buffer_event_data(event); \ | |
187 | \ | |
188 | tstruct; \ | |
189 | \ | |
190 | trace_current_buffer_unlock_commit(event, irq_flags, pc); \ | |
191 | } \ | |
192 | \ | |
193 | static int ftrace_raw_reg_event_##call(void) \ | |
194 | { \ | |
195 | int ret; \ | |
196 | \ | |
197 | ret = register_trace_##call(ftrace_raw_event_##call); \ | |
633ddaa7 | 198 | if (ret) \ |
c32e827b | 199 | pr_info("event trace: Could not activate trace point " \ |
633ddaa7 | 200 | "probe to " #call "\n"); \ |
c32e827b SR |
201 | return ret; \ |
202 | } \ | |
203 | \ | |
204 | static void ftrace_raw_unreg_event_##call(void) \ | |
205 | { \ | |
206 | unregister_trace_##call(ftrace_raw_event_##call); \ | |
207 | } \ | |
208 | \ | |
209 | static struct trace_event ftrace_event_type_##call = { \ | |
210 | .trace = ftrace_raw_output_##call, \ | |
211 | }; \ | |
212 | \ | |
213 | static int ftrace_raw_init_event_##call(void) \ | |
214 | { \ | |
215 | int id; \ | |
216 | \ | |
217 | id = register_ftrace_event(&ftrace_event_type_##call); \ | |
218 | if (!id) \ | |
219 | return -ENODEV; \ | |
220 | event_##call.id = id; \ | |
221 | return 0; \ | |
222 | } \ | |
223 | \ | |
224 | static struct ftrace_event_call __used \ | |
225 | __attribute__((__aligned__(4))) \ | |
226 | __attribute__((section("_ftrace_events"))) event_##call = { \ | |
227 | .name = #call, \ | |
9cc26a26 | 228 | .system = __stringify(TRACE_SYSTEM), \ |
c32e827b SR |
229 | .regfunc = ftrace_reg_event_##call, \ |
230 | .unregfunc = ftrace_unreg_event_##call, \ | |
231 | .raw_init = ftrace_raw_init_event_##call, \ | |
232 | .raw_reg = ftrace_raw_reg_event_##call, \ | |
233 | .raw_unreg = ftrace_raw_unreg_event_##call, \ | |
981d081e | 234 | .show_format = ftrace_format_##call, \ |
c32e827b | 235 | } |