diff options
author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2008-05-12 15:21:10 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 16:29:25 -0400 |
commit | 5b82a1b08a00b2adca3d9dd9777efff40b7aaaa1 (patch) | |
tree | 4dcce4af592ca177bee3dfeb34f9b482d142e713 /kernel/trace/trace_sched_wakeup.c | |
parent | 0aa977f592f17004f9d1d545f2e1bb9ea71896c3 (diff) |
Port ftrace to markers
Porting ftrace to the marker infrastructure.
Don't need to chain to the wakeup tracer from the sched tracer, because markers
support multiple probes connected.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
CC: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/trace/trace_sched_wakeup.c')
-rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 106 |
1 files changed, 100 insertions, 6 deletions
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 5948011006bc..5d2fb48e47f8 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kallsyms.h> | 15 | #include <linux/kallsyms.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <linux/ftrace.h> | 17 | #include <linux/ftrace.h> |
18 | #include <linux/marker.h> | ||
18 | 19 | ||
19 | #include "trace.h" | 20 | #include "trace.h" |
20 | 21 | ||
@@ -44,11 +45,13 @@ static int report_latency(cycle_t delta) | |||
44 | return 1; | 45 | return 1; |
45 | } | 46 | } |
46 | 47 | ||
47 | void | 48 | static void notrace |
48 | wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) | 49 | wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, |
50 | struct task_struct *next) | ||
49 | { | 51 | { |
50 | unsigned long latency = 0, t0 = 0, t1 = 0; | 52 | unsigned long latency = 0, t0 = 0, t1 = 0; |
51 | struct trace_array *tr = wakeup_trace; | 53 | struct trace_array **ptr = private; |
54 | struct trace_array *tr = *ptr; | ||
52 | struct trace_array_cpu *data; | 55 | struct trace_array_cpu *data; |
53 | cycle_t T0, T1, delta; | 56 | cycle_t T0, T1, delta; |
54 | unsigned long flags; | 57 | unsigned long flags; |
@@ -113,6 +116,31 @@ out: | |||
113 | atomic_dec(&tr->data[cpu]->disabled); | 116 | atomic_dec(&tr->data[cpu]->disabled); |
114 | } | 117 | } |
115 | 118 | ||
119 | static notrace void | ||
120 | sched_switch_callback(void *probe_data, void *call_data, | ||
121 | const char *format, va_list *args) | ||
122 | { | ||
123 | struct task_struct *prev; | ||
124 | struct task_struct *next; | ||
125 | struct rq *__rq; | ||
126 | |||
127 | /* skip prev_pid %d next_pid %d prev_state %ld */ | ||
128 | (void)va_arg(*args, int); | ||
129 | (void)va_arg(*args, int); | ||
130 | (void)va_arg(*args, long); | ||
131 | __rq = va_arg(*args, typeof(__rq)); | ||
132 | prev = va_arg(*args, typeof(prev)); | ||
133 | next = va_arg(*args, typeof(next)); | ||
134 | |||
135 | tracing_record_cmdline(prev); | ||
136 | |||
137 | /* | ||
138 | * If tracer_switch_func only points to the local | ||
139 | * switch func, it still needs the ptr passed to it. | ||
140 | */ | ||
141 | wakeup_sched_switch(probe_data, __rq, prev, next); | ||
142 | } | ||
143 | |||
116 | static void __wakeup_reset(struct trace_array *tr) | 144 | static void __wakeup_reset(struct trace_array *tr) |
117 | { | 145 | { |
118 | struct trace_array_cpu *data; | 146 | struct trace_array_cpu *data; |
@@ -188,19 +216,68 @@ out: | |||
188 | atomic_dec(&tr->data[cpu]->disabled); | 216 | atomic_dec(&tr->data[cpu]->disabled); |
189 | } | 217 | } |
190 | 218 | ||
191 | void wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) | 219 | static notrace void |
220 | wake_up_callback(void *probe_data, void *call_data, | ||
221 | const char *format, va_list *args) | ||
192 | { | 222 | { |
223 | struct trace_array **ptr = probe_data; | ||
224 | struct trace_array *tr = *ptr; | ||
225 | struct task_struct *curr; | ||
226 | struct task_struct *task; | ||
227 | struct rq *__rq; | ||
228 | |||
193 | if (likely(!tracer_enabled)) | 229 | if (likely(!tracer_enabled)) |
194 | return; | 230 | return; |
195 | 231 | ||
232 | /* Skip pid %d state %ld */ | ||
233 | (void)va_arg(*args, int); | ||
234 | (void)va_arg(*args, long); | ||
235 | /* now get the meat: "rq %p task %p rq->curr %p" */ | ||
236 | __rq = va_arg(*args, typeof(__rq)); | ||
237 | task = va_arg(*args, typeof(task)); | ||
238 | curr = va_arg(*args, typeof(curr)); | ||
239 | |||
240 | tracing_record_cmdline(task); | ||
196 | tracing_record_cmdline(curr); | 241 | tracing_record_cmdline(curr); |
197 | tracing_record_cmdline(wakee); | ||
198 | 242 | ||
199 | wakeup_check_start(wakeup_trace, wakee, curr); | 243 | wakeup_check_start(tr, task, curr); |
200 | } | 244 | } |
201 | 245 | ||
202 | static void start_wakeup_tracer(struct trace_array *tr) | 246 | static void start_wakeup_tracer(struct trace_array *tr) |
203 | { | 247 | { |
248 | int ret; | ||
249 | |||
250 | ret = marker_probe_register("kernel_sched_wakeup", | ||
251 | "pid %d state %ld ## rq %p task %p rq->curr %p", | ||
252 | wake_up_callback, | ||
253 | &wakeup_trace); | ||
254 | if (ret) { | ||
255 | pr_info("wakeup trace: Couldn't add marker" | ||
256 | " probe to kernel_sched_wakeup\n"); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | ret = marker_probe_register("kernel_sched_wakeup_new", | ||
261 | "pid %d state %ld ## rq %p task %p rq->curr %p", | ||
262 | wake_up_callback, | ||
263 | &wakeup_trace); | ||
264 | if (ret) { | ||
265 | pr_info("wakeup trace: Couldn't add marker" | ||
266 | " probe to kernel_sched_wakeup_new\n"); | ||
267 | goto fail_deprobe; | ||
268 | } | ||
269 | |||
270 | ret = marker_probe_register("kernel_sched_schedule", | ||
271 | "prev_pid %d next_pid %d prev_state %ld " | ||
272 | "## rq %p prev %p next %p", | ||
273 | sched_switch_callback, | ||
274 | &wakeup_trace); | ||
275 | if (ret) { | ||
276 | pr_info("sched trace: Couldn't add marker" | ||
277 | " probe to kernel_sched_schedule\n"); | ||
278 | goto fail_deprobe_wake_new; | ||
279 | } | ||
280 | |||
204 | wakeup_reset(tr); | 281 | wakeup_reset(tr); |
205 | 282 | ||
206 | /* | 283 | /* |
@@ -215,11 +292,28 @@ static void start_wakeup_tracer(struct trace_array *tr) | |||
215 | tracer_enabled = 1; | 292 | tracer_enabled = 1; |
216 | 293 | ||
217 | return; | 294 | return; |
295 | fail_deprobe_wake_new: | ||
296 | marker_probe_unregister("kernel_sched_wakeup_new", | ||
297 | wake_up_callback, | ||
298 | &wakeup_trace); | ||
299 | fail_deprobe: | ||
300 | marker_probe_unregister("kernel_sched_wakeup", | ||
301 | wake_up_callback, | ||
302 | &wakeup_trace); | ||
218 | } | 303 | } |
219 | 304 | ||
220 | static void stop_wakeup_tracer(struct trace_array *tr) | 305 | static void stop_wakeup_tracer(struct trace_array *tr) |
221 | { | 306 | { |
222 | tracer_enabled = 0; | 307 | tracer_enabled = 0; |
308 | marker_probe_unregister("kernel_sched_schedule", | ||
309 | sched_switch_callback, | ||
310 | &wakeup_trace); | ||
311 | marker_probe_unregister("kernel_sched_wakeup_new", | ||
312 | wake_up_callback, | ||
313 | &wakeup_trace); | ||
314 | marker_probe_unregister("kernel_sched_wakeup", | ||
315 | wake_up_callback, | ||
316 | &wakeup_trace); | ||
223 | } | 317 | } |
224 | 318 | ||
225 | static void wakeup_tracer_init(struct trace_array *tr) | 319 | static void wakeup_tracer_init(struct trace_array *tr) |