aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-05-12 15:20:44 -0400
committerThomas Gleixner <tglx@linutronix.de>2008-05-23 14:40:36 -0400
commit60a11774b38fef1ab90b18c5353bd1c7c4d311c8 (patch)
treee2a6fd066b0dba6dcd776d07383e2932055cf66a /kernel/trace/trace.c
parente1c08bdd9fa73e44096e5a82c0d5928b04ab02c8 (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.c63
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 @@
32unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; 32unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX;
33unsigned long __read_mostly tracing_thresh; 33unsigned long __read_mostly tracing_thresh;
34 34
35static int tracing_disabled = 1;
36
35static long notrace 37static long notrace
36ns2usecs(cycle_t nsec) 38ns2usecs(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
1024int tracing_open_generic(struct inode *inode, struct file *filp) 1068int 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
1455static __init void tracer_init_debugfs(void) 1510static __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
1684device_initcall(tracer_alloc_buffers); 1743fs_initcall(tracer_alloc_buffers);