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 | |
| 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')
| -rw-r--r-- | kernel/trace/trace.h | 20 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_switch.c | 171 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 106 |
3 files changed, 244 insertions, 53 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8845033ab49d..f5de0601b408 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -234,25 +234,10 @@ void update_max_tr_single(struct trace_array *tr, | |||
| 234 | 234 | ||
| 235 | extern cycle_t ftrace_now(int cpu); | 235 | extern cycle_t ftrace_now(int cpu); |
| 236 | 236 | ||
| 237 | #ifdef CONFIG_SCHED_TRACER | ||
| 238 | extern void | ||
| 239 | wakeup_sched_switch(struct task_struct *prev, struct task_struct *next); | ||
| 240 | extern void | ||
| 241 | wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr); | ||
| 242 | #else | ||
| 243 | static inline void | ||
| 244 | wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) | ||
| 245 | { | ||
| 246 | } | ||
| 247 | static inline void | ||
| 248 | wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr) | ||
| 249 | { | ||
| 250 | } | ||
| 251 | #endif | ||
| 252 | |||
| 253 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER | 237 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER |
| 254 | typedef void | 238 | typedef void |
| 255 | (*tracer_switch_func_t)(void *private, | 239 | (*tracer_switch_func_t)(void *private, |
| 240 | void *__rq, | ||
| 256 | struct task_struct *prev, | 241 | struct task_struct *prev, |
| 257 | struct task_struct *next); | 242 | struct task_struct *next); |
| 258 | 243 | ||
| @@ -262,9 +247,6 @@ struct tracer_switch_ops { | |||
| 262 | struct tracer_switch_ops *next; | 247 | struct tracer_switch_ops *next; |
| 263 | }; | 248 | }; |
| 264 | 249 | ||
| 265 | extern int register_tracer_switch(struct tracer_switch_ops *ops); | ||
| 266 | extern int unregister_tracer_switch(struct tracer_switch_ops *ops); | ||
| 267 | |||
| 268 | #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ | 250 | #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ |
| 269 | 251 | ||
| 270 | #ifdef CONFIG_DYNAMIC_FTRACE | 252 | #ifdef CONFIG_DYNAMIC_FTRACE |
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index a3376478fc2c..d25ffa5eaf2b 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c | |||
| @@ -16,11 +16,14 @@ | |||
| 16 | 16 | ||
| 17 | static struct trace_array *ctx_trace; | 17 | static struct trace_array *ctx_trace; |
| 18 | static int __read_mostly tracer_enabled; | 18 | static int __read_mostly tracer_enabled; |
| 19 | static atomic_t sched_ref; | ||
| 19 | 20 | ||
| 20 | static void | 21 | static void |
| 21 | ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) | 22 | sched_switch_func(void *private, void *__rq, struct task_struct *prev, |
| 23 | struct task_struct *next) | ||
| 22 | { | 24 | { |
| 23 | struct trace_array *tr = ctx_trace; | 25 | struct trace_array **ptr = private; |
| 26 | struct trace_array *tr = *ptr; | ||
| 24 | struct trace_array_cpu *data; | 27 | struct trace_array_cpu *data; |
| 25 | unsigned long flags; | 28 | unsigned long flags; |
| 26 | long disabled; | 29 | long disabled; |
| @@ -41,10 +44,40 @@ ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next) | |||
| 41 | local_irq_restore(flags); | 44 | local_irq_restore(flags); |
| 42 | } | 45 | } |
| 43 | 46 | ||
| 47 | static notrace void | ||
| 48 | sched_switch_callback(void *probe_data, void *call_data, | ||
| 49 | const char *format, va_list *args) | ||
| 50 | { | ||
| 51 | struct task_struct *prev; | ||
| 52 | struct task_struct *next; | ||
| 53 | struct rq *__rq; | ||
| 54 | |||
| 55 | if (!atomic_read(&sched_ref)) | ||
| 56 | return; | ||
| 57 | |||
| 58 | /* skip prev_pid %d next_pid %d prev_state %ld */ | ||
| 59 | (void)va_arg(*args, int); | ||
| 60 | (void)va_arg(*args, int); | ||
| 61 | (void)va_arg(*args, long); | ||
| 62 | __rq = va_arg(*args, typeof(__rq)); | ||
| 63 | prev = va_arg(*args, typeof(prev)); | ||
| 64 | next = va_arg(*args, typeof(next)); | ||
| 65 | |||
| 66 | tracing_record_cmdline(prev); | ||
| 67 | |||
| 68 | /* | ||
| 69 | * If tracer_switch_func only points to the local | ||
| 70 | * switch func, it still needs the ptr passed to it. | ||
| 71 | */ | ||
| 72 | sched_switch_func(probe_data, __rq, prev, next); | ||
| 73 | } | ||
| 74 | |||
| 44 | static void | 75 | static void |
| 45 | wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) | 76 | wakeup_func(void *private, void *__rq, struct task_struct *wakee, struct |
| 77 | task_struct *curr) | ||
| 46 | { | 78 | { |
| 47 | struct trace_array *tr = ctx_trace; | 79 | struct trace_array **ptr = private; |
| 80 | struct trace_array *tr = *ptr; | ||
| 48 | struct trace_array_cpu *data; | 81 | struct trace_array_cpu *data; |
| 49 | unsigned long flags; | 82 | unsigned long flags; |
| 50 | long disabled; | 83 | long disabled; |
| @@ -67,35 +100,29 @@ wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr) | |||
| 67 | local_irq_restore(flags); | 100 | local_irq_restore(flags); |
| 68 | } | 101 | } |
| 69 | 102 | ||
| 70 | void | 103 | static notrace void |
| 71 | ftrace_ctx_switch(void *__rq, struct task_struct *prev, | 104 | wake_up_callback(void *probe_data, void *call_data, |
| 72 | struct task_struct *next) | 105 | const char *format, va_list *args) |
| 73 | { | 106 | { |
| 74 | if (unlikely(atomic_read(&trace_record_cmdline_enabled))) | 107 | struct task_struct *curr; |
| 75 | tracing_record_cmdline(prev); | 108 | struct task_struct *task; |
| 109 | struct rq *__rq; | ||
| 76 | 110 | ||
| 77 | /* | 111 | if (likely(!tracer_enabled)) |
| 78 | * If tracer_switch_func only points to the local | 112 | return; |
| 79 | * switch func, it still needs the ptr passed to it. | ||
| 80 | */ | ||
| 81 | ctx_switch_func(__rq, prev, next); | ||
| 82 | 113 | ||
| 83 | /* | 114 | /* Skip pid %d state %ld */ |
| 84 | * Chain to the wakeup tracer (this is a NOP if disabled): | 115 | (void)va_arg(*args, int); |
| 85 | */ | 116 | (void)va_arg(*args, long); |
| 86 | wakeup_sched_switch(prev, next); | 117 | /* now get the meat: "rq %p task %p rq->curr %p" */ |
| 87 | } | 118 | __rq = va_arg(*args, typeof(__rq)); |
| 119 | task = va_arg(*args, typeof(task)); | ||
| 120 | curr = va_arg(*args, typeof(curr)); | ||
| 88 | 121 | ||
| 89 | void | 122 | tracing_record_cmdline(task); |
| 90 | ftrace_wake_up_task(void *__rq, struct task_struct *wakee, | 123 | tracing_record_cmdline(curr); |
| 91 | struct task_struct *curr) | ||
| 92 | { | ||
| 93 | wakeup_func(__rq, wakee, curr); | ||
| 94 | 124 | ||
| 95 | /* | 125 | wakeup_func(probe_data, __rq, task, curr); |
| 96 | * Chain to the wakeup tracer (this is a NOP if disabled): | ||
| 97 | */ | ||
| 98 | wakeup_sched_wakeup(wakee, curr); | ||
| 99 | } | 126 | } |
| 100 | 127 | ||
| 101 | void | 128 | void |
| @@ -132,15 +159,95 @@ static void sched_switch_reset(struct trace_array *tr) | |||
| 132 | tracing_reset(tr->data[cpu]); | 159 | tracing_reset(tr->data[cpu]); |
| 133 | } | 160 | } |
| 134 | 161 | ||
| 162 | static int tracing_sched_register(void) | ||
| 163 | { | ||
| 164 | int ret; | ||
| 165 | |||
| 166 | ret = marker_probe_register("kernel_sched_wakeup", | ||
| 167 | "pid %d state %ld ## rq %p task %p rq->curr %p", | ||
| 168 | wake_up_callback, | ||
| 169 | &ctx_trace); | ||
| 170 | if (ret) { | ||
| 171 | pr_info("wakeup trace: Couldn't add marker" | ||
| 172 | " probe to kernel_sched_wakeup\n"); | ||
| 173 | return ret; | ||
| 174 | } | ||
| 175 | |||
| 176 | ret = marker_probe_register("kernel_sched_wakeup_new", | ||
| 177 | "pid %d state %ld ## rq %p task %p rq->curr %p", | ||
| 178 | wake_up_callback, | ||
