diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
| commit | 9efe21cb82b5dbe3b0b2ae4de4eccc64ecb94e95 (patch) | |
| tree | 7ff8833745d2f268f897f6fa4a27263b4a572245 /kernel/trace/trace.c | |
| parent | de18836e447c2dc30120c0919b8db8ddc0401cc4 (diff) | |
| parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff) | |
Merge branch 'linus' into irq/threaded
Conflicts:
include/linux/irq.h
kernel/irq/handle.c
Diffstat (limited to 'kernel/trace/trace.c')
| -rw-r--r-- | kernel/trace/trace.c | 3034 |
1 files changed, 1689 insertions, 1345 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 17bb88d86ac..a0174a40c56 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -11,32 +11,33 @@ | |||
| 11 | * Copyright (C) 2004-2006 Ingo Molnar | 11 | * Copyright (C) 2004-2006 Ingo Molnar |
| 12 | * Copyright (C) 2004 William Lee Irwin III | 12 | * Copyright (C) 2004 William Lee Irwin III |
| 13 | */ | 13 | */ |
| 14 | #include <linux/ring_buffer.h> | ||
| 14 | #include <linux/utsrelease.h> | 15 | #include <linux/utsrelease.h> |
| 16 | #include <linux/stacktrace.h> | ||
| 17 | #include <linux/writeback.h> | ||
| 15 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
| 16 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 17 | #include <linux/notifier.h> | 20 | #include <linux/notifier.h> |
| 21 | #include <linux/irqflags.h> | ||
| 18 | #include <linux/debugfs.h> | 22 | #include <linux/debugfs.h> |
| 19 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
| 20 | #include <linux/hardirq.h> | 24 | #include <linux/hardirq.h> |
| 21 | #include <linux/linkage.h> | 25 | #include <linux/linkage.h> |
| 22 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
| 27 | #include <linux/kprobes.h> | ||
| 23 | #include <linux/ftrace.h> | 28 | #include <linux/ftrace.h> |
| 24 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 25 | #include <linux/percpu.h> | 30 | #include <linux/percpu.h> |
| 31 | #include <linux/splice.h> | ||
| 26 | #include <linux/kdebug.h> | 32 | #include <linux/kdebug.h> |
| 27 | #include <linux/ctype.h> | 33 | #include <linux/ctype.h> |
| 28 | #include <linux/init.h> | 34 | #include <linux/init.h> |
| 29 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
| 30 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
| 31 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
| 32 | #include <linux/kprobes.h> | ||
| 33 | #include <linux/writeback.h> | ||
| 34 | |||
| 35 | #include <linux/stacktrace.h> | ||
| 36 | #include <linux/ring_buffer.h> | ||
| 37 | #include <linux/irqflags.h> | ||
| 38 | 38 | ||
| 39 | #include "trace.h" | 39 | #include "trace.h" |
| 40 | #include "trace_output.h" | ||
| 40 | 41 | ||
| 41 | #define TRACE_BUFFER_FLAGS (RB_FL_OVERWRITE) | 42 | #define TRACE_BUFFER_FLAGS (RB_FL_OVERWRITE) |
| 42 | 43 | ||
| @@ -44,14 +45,25 @@ unsigned long __read_mostly tracing_max_latency; | |||
| 44 | unsigned long __read_mostly tracing_thresh; | 45 | unsigned long __read_mostly tracing_thresh; |
| 45 | 46 | ||
| 46 | /* | 47 | /* |
| 48 | * On boot up, the ring buffer is set to the minimum size, so that | ||
| 49 | * we do not waste memory on systems that are not using tracing. | ||
| 50 | */ | ||
| 51 | static int ring_buffer_expanded; | ||
| 52 | |||
| 53 | /* | ||
| 47 | * We need to change this state when a selftest is running. | 54 | * We need to change this state when a selftest is running. |
| 48 | * A selftest will lurk into the ring-buffer to count the | 55 | * A selftest will lurk into the ring-buffer to count the |
| 49 | * entries inserted during the selftest although some concurrent | 56 | * entries inserted during the selftest although some concurrent |
| 50 | * insertions into the ring-buffer such as ftrace_printk could occurred | 57 | * insertions into the ring-buffer such as trace_printk could occurred |
| 51 | * at the same time, giving false positive or negative results. | 58 | * at the same time, giving false positive or negative results. |
| 52 | */ | 59 | */ |
| 53 | static bool __read_mostly tracing_selftest_running; | 60 | static bool __read_mostly tracing_selftest_running; |
| 54 | 61 | ||
| 62 | /* | ||
| 63 | * If a tracer is running, we do not want to run SELFTEST. | ||
| 64 | */ | ||
| 65 | static bool __read_mostly tracing_selftest_disabled; | ||
| 66 | |||
| 55 | /* For tracers that don't implement custom flags */ | 67 | /* For tracers that don't implement custom flags */ |
| 56 | static struct tracer_opt dummy_tracer_opt[] = { | 68 | static struct tracer_opt dummy_tracer_opt[] = { |
| 57 | { } | 69 | { } |
| @@ -73,7 +85,7 @@ static int dummy_set_flag(u32 old_flags, u32 bit, int set) | |||
| 73 | * of the tracer is successful. But that is the only place that sets | 85 | * of the tracer is successful. But that is the only place that sets |
| 74 | * this back to zero. | 86 | * this back to zero. |
| 75 | */ | 87 | */ |
| 76 | int tracing_disabled = 1; | 88 | static int tracing_disabled = 1; |
| 77 | 89 | ||
| 78 | static DEFINE_PER_CPU(local_t, ftrace_cpu_disabled); | 90 | static DEFINE_PER_CPU(local_t, ftrace_cpu_disabled); |
| 79 | 91 | ||
| @@ -91,6 +103,9 @@ static inline void ftrace_enable_cpu(void) | |||
| 91 | 103 | ||
| 92 | static cpumask_var_t __read_mostly tracing_buffer_mask; | 104 | static cpumask_var_t __read_mostly tracing_buffer_mask; |
| 93 | 105 | ||
| 106 | /* Define which cpu buffers are currently read in trace_pipe */ | ||
| 107 | static cpumask_var_t tracing_reader_cpumask; | ||
| 108 | |||
| 94 | #define for_each_tracing_cpu(cpu) \ | 109 | #define for_each_tracing_cpu(cpu) \ |
| 95 | for_each_cpu(cpu, tracing_buffer_mask) | 110 | for_each_cpu(cpu, tracing_buffer_mask) |
| 96 | 111 | ||
| @@ -109,14 +124,21 @@ static cpumask_var_t __read_mostly tracing_buffer_mask; | |||
| 109 | */ | 124 | */ |
| 110 | int ftrace_dump_on_oops; | 125 | int ftrace_dump_on_oops; |
| 111 | 126 | ||
| 112 | static int tracing_set_tracer(char *buf); | 127 | static int tracing_set_tracer(const char *buf); |
| 128 | |||
| 129 | #define BOOTUP_TRACER_SIZE 100 | ||
| 130 | static char bootup_tracer_buf[BOOTUP_TRACER_SIZE] __initdata; | ||
| 131 | static char *default_bootup_tracer; | ||
| 113 | 132 | ||
| 114 | static int __init set_ftrace(char *str) | 133 | static int __init set_ftrace(char *str) |
| 115 | { | 134 | { |
| 116 | tracing_set_tracer(str); | 135 | strncpy(bootup_tracer_buf, str, BOOTUP_TRACER_SIZE); |
| 136 | default_bootup_tracer = bootup_tracer_buf; | ||
| 137 | /* We are using ftrace early, expand it */ | ||
| 138 | ring_buffer_expanded = 1; | ||
| 117 | return 1; | 139 | return 1; |
| 118 | } | 140 | } |
| 119 | __setup("ftrace", set_ftrace); | 141 | __setup("ftrace=", set_ftrace); |
| 120 | 142 | ||
| 121 | static int __init set_ftrace_dump_on_oops(char *str) | 143 | static int __init set_ftrace_dump_on_oops(char *str) |
| 122 | { | 144 | { |
| @@ -133,13 +155,6 @@ ns2usecs(cycle_t nsec) | |||
| 133 | return nsec; | 155 | return nsec; |
| 134 | } | 156 | } |
| 135 | 157 | ||
| 136 | cycle_t ftrace_now(int cpu) | ||
| 137 | { | ||
| 138 | u64 ts = ring_buffer_time_stamp(cpu); | ||
| 139 | ring_buffer_normalize_time_stamp(cpu, &ts); | ||
| 140 | return ts; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | 158 | /* |
| 144 | * The global_trace is the descriptor that holds the tracing | 159 | * The global_trace is the descriptor that holds the tracing |
| 145 | * buffers for the live tracing. For each CPU, it contains | 160 | * buffers for the live tracing. For each CPU, it contains |
| @@ -156,6 +171,20 @@ static struct trace_array global_trace; | |||
| 156 | 171 | ||
| 157 | static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); | 172 | static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); |
| 158 | 173 | ||
| 174 | cycle_t ftrace_now(int cpu) | ||
| 175 | { | ||
| 176 | u64 ts; | ||
| 177 | |||
| 178 | /* Early boot up does not have a buffer yet */ | ||
| 179 | if (!global_trace.buffer) | ||
| 180 | return trace_clock_local(); | ||
| 181 | |||
| 182 | ts = ring_buffer_time_stamp(global_trace.buffer, cpu); | ||
| 183 | ring_buffer_normalize_time_stamp(global_trace.buffer, cpu, &ts); | ||
| 184 | |||
| 185 | return ts; | ||
| 186 | } | ||
| 187 | |||
| 159 | /* | 188 | /* |
| 160 | * The max_tr is used to snapshot the global_trace when a maximum | 189 | * The max_tr is used to snapshot the global_trace when a maximum |
| 161 | * latency is reached. Some tracers will use this to store a maximum | 190 | * latency is reached. Some tracers will use this to store a maximum |
| @@ -186,9 +215,6 @@ int tracing_is_enabled(void) | |||
| 186 | return tracer_enabled; | 215 | return tracer_enabled; |
| 187 | } | 216 | } |
| 188 | 217 | ||
| 189 | /* function tracing enabled */ | ||
| 190 | int ftrace_function_enabled; | ||
| 191 | |||
| 192 | /* | 218 | /* |
| 193 | * trace_buf_size is the size in bytes that is allocated | 219 | * trace_buf_size is the size in bytes that is allocated |
| 194 | * for a buffer. Note, the number of bytes is always rounded | 220 | * for a buffer. Note, the number of bytes is always rounded |
| @@ -229,7 +255,7 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); | |||
| 229 | 255 | ||
| 230 | /* trace_flags holds trace_options default values */ | 256 | /* trace_flags holds trace_options default values */ |
| 231 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | | 257 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | |
| 232 | TRACE_ITER_ANNOTATE; | 258 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME; |
| 233 | 259 | ||
| 234 | /** | 260 | /** |
| 235 | * trace_wake_up - wake up tasks waiting for trace input | 261 | * trace_wake_up - wake up tasks waiting for trace input |
| @@ -280,13 +306,17 @@ static const char *trace_options[] = { | |||
| 280 | "block", | 306 | "block", |
| 281 | "stacktrace", | 307 | "stacktrace", |
| 282 | "sched-tree", | 308 | "sched-tree", |
| 283 | "ftrace_printk", | 309 | "trace_printk", |
| 284 | "ftrace_preempt", | ||
