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 | * { | |
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 | } |