diff options
author | Steven Rostedt <srostedt@redhat.com> | 2008-05-12 15:20:44 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 14:40:36 -0400 |
commit | 60a11774b38fef1ab90b18c5353bd1c7c4d311c8 (patch) | |
tree | e2a6fd066b0dba6dcd776d07383e2932055cf66a /kernel/trace/trace.c | |
parent | e1c08bdd9fa73e44096e5a82c0d5928b04ab02c8 (diff) |
ftrace: add self-tests
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9bad2379115a..f6d026f17dbb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -32,6 +32,8 @@ | |||
32 | unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; | 32 | unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; |
33 | unsigned long __read_mostly tracing_thresh; | 33 | unsigned long __read_mostly tracing_thresh; |
34 | 34 | ||
35 | static int tracing_disabled = 1; | ||
36 | |||
35 | static long notrace | 37 | static long notrace |
36 | ns2usecs(cycle_t nsec) | 38 | ns2usecs(cycle_t nsec) |
37 | { | 39 | { |
@@ -217,11 +219,48 @@ int register_tracer(struct tracer *type) | |||
217 | } | 219 | } |
218 | } | 220 | } |
219 | 221 | ||
222 | #ifdef CONFIG_FTRACE_STARTUP_TEST | ||
223 | if (type->selftest) { | ||
224 | struct tracer *saved_tracer = current_trace; | ||
225 | struct trace_array_cpu *data; | ||
226 | struct trace_array *tr = &global_trace; | ||
227 | int saved_ctrl = tr->ctrl; | ||
228 | int i; | ||
229 | /* | ||
230 | * Run a selftest on this tracer. | ||
231 | * Here we reset the trace buffer, and set the current | ||
232 | * tracer to be this tracer. The tracer can then run some | ||
233 | * internal tracing to verify that everything is in order. | ||
234 | * If we fail, we do not register this tracer. | ||
235 | */ | ||
236 | for_each_possible_cpu(i) { | ||
237 | if (!data->trace) | ||
238 | continue; | ||
239 | data = tr->data[i]; | ||
240 | tracing_reset(data); | ||
241 | } | ||
242 | current_trace = type; | ||
243 | tr->ctrl = 0; | ||
244 | /* the test is responsible for initializing and enabling */ | ||
245 | pr_info("Testing tracer %s: ", type->name); | ||
246 | ret = type->selftest(type, tr); | ||
247 | /* the test is responsible for resetting too */ | ||
248 | current_trace = saved_tracer; | ||
249 | tr->ctrl = saved_ctrl; | ||
250 | if (ret) { | ||
251 | printk(KERN_CONT "FAILED!\n"); | ||
252 | goto out; | ||
253 | } | ||
254 | printk(KERN_CONT "PASSED\n"); | ||
255 | } | ||
256 | #endif | ||
257 | |||
220 | type->next = trace_types; | 258 | type->next = trace_types; |
221 | trace_types = type; | 259 | trace_types = type; |
222 | len = strlen(type->name); | 260 | len = strlen(type->name); |
223 | if (len > max_tracer_type_len) | 261 | if (len > max_tracer_type_len) |
224 | max_tracer_type_len = len; | 262 | max_tracer_type_len = len; |
263 | |||
225 | out: | 264 | out: |
226 | mutex_unlock(&trace_types_lock); | 265 | mutex_unlock(&trace_types_lock); |
227 | 266 | ||
@@ -985,6 +1024,11 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) | |||
985 | { | 1024 | { |
986 | struct trace_iterator *iter; | 1025 | struct trace_iterator *iter; |
987 | 1026 | ||
1027 | if (tracing_disabled) { | ||
1028 | *ret = -ENODEV; | ||
1029 | return NULL; | ||
1030 | } | ||
1031 | |||
988 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 1032 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
989 | if (!iter) { | 1033 | if (!iter) { |
990 | *ret = -ENOMEM; | 1034 | *ret = -ENOMEM; |
@@ -1023,6 +1067,9 @@ __tracing_open(struct inode *inode, struct file *file, int *ret) | |||
1023 | 1067 | ||
1024 | int tracing_open_generic(struct inode *inode, struct file *filp) | 1068 | int tracing_open_generic(struct inode *inode, struct file *filp) |
1025 | { | 1069 | { |
1070 | if (tracing_disabled) | ||
1071 | return -ENODEV; | ||
1072 | |||
1026 | filp->private_data = inode->i_private; | 1073 | filp->private_data = inode->i_private; |
1027 | return 0; | 1074 | return 0; |
1028 | } | 1075 | } |
@@ -1128,6 +1175,9 @@ static int show_traces_open(struct inode *inode, struct file *file) | |||
1128 | { | 1175 | { |
1129 | int ret; | 1176 | int ret; |
1130 | 1177 | ||
1178 | if (tracing_disabled) | ||
1179 | return -ENODEV; | ||
1180 | |||
1131 | ret = seq_open(file, &show_traces_seq_ops); | 1181 | ret = seq_open(file, &show_traces_seq_ops); |
1132 | if (!ret) { | 1182 | if (!ret) { |
1133 | struct seq_file *m = file->private_data; | 1183 | struct seq_file *m = file->private_data; |
@@ -1452,6 +1502,11 @@ struct dentry *tracing_init_dentry(void) | |||
1452 | return d_tracer; | 1502 | return d_tracer; |
1453 | } | 1503 | } |
1454 | 1504 | ||
1505 | #ifdef CONFIG_FTRACE_SELFTEST | ||
1506 | /* Let selftest have access to static functions in this file */ | ||
1507 | #include "trace_selftest.c" | ||
1508 | #endif | ||
1509 | |||
1455 | static __init void tracer_init_debugfs(void) | 1510 | static __init void tracer_init_debugfs(void) |
1456 | { | 1511 | { |
1457 | struct dentry *d_tracer; | 1512 | struct dentry *d_tracer; |
@@ -1585,6 +1640,7 @@ __init static int tracer_alloc_buffers(void) | |||
1585 | void *array; | 1640 | void *array; |
1586 | struct page *page; | 1641 | struct page *page; |
1587 | int pages = 0; | 1642 | int pages = 0; |
1643 | int ret = -ENOMEM; | ||
1588 | int i; | 1644 | int i; |
1589 | 1645 | ||
1590 | /* Allocate the first page for all buffers */ | 1646 | /* Allocate the first page for all buffers */ |
@@ -1650,6 +1706,9 @@ __init static int tracer_alloc_buffers(void) | |||
1650 | register_tracer(&no_tracer); | 1706 | register_tracer(&no_tracer); |
1651 | current_trace = &no_tracer; | 1707 | current_trace = &no_tracer; |
1652 | 1708 | ||
1709 | /* All seems OK, enable tracing */ | ||
1710 | tracing_disabled = 0; | ||
1711 | |||
1653 | return 0; | 1712 | return 0; |
1654 | 1713 | ||
1655 | free_buffers: | 1714 | free_buffers: |
@@ -1678,7 +1737,7 @@ __init static int tracer_alloc_buffers(void) | |||
1678 | } | 1737 | } |
1679 | #endif | 1738 | #endif |
1680 | } | 1739 | } |
1681 | return -ENOMEM; | 1740 | return ret; |
1682 | } | 1741 | } |
1683 | 1742 | ||
1684 | device_initcall(tracer_alloc_buffers); | 1743 | fs_initcall(tracer_alloc_buffers); |