Merge branch 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
authorIngo Molnar <mingo@elte.hu>
Tue, 11 Nov 2008 20:34:07 +0000 (21:34 +0100)
committerIngo Molnar <mingo@elte.hu>
Tue, 11 Nov 2008 20:34:07 +0000 (21:34 +0100)
include/linux/ring_buffer.h
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c

index 536b0ca..e097c2e 100644 (file)
@@ -120,6 +120,9 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
 u64 ring_buffer_time_stamp(int cpu);
 void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
 
+void tracing_on(void);
+void tracing_off(void);
+
 enum ring_buffer_flags {
        RB_FL_OVERWRITE         = 1 << 0,
 };
index 4a39d24..14fa522 100644 (file)
@@ -185,7 +185,6 @@ enum {
 };
 
 static int ftrace_filtered;
-static int tracing_on;
 
 static LIST_HEAD(ftrace_new_addrs);
 
@@ -506,13 +505,10 @@ static int __ftrace_modify_code(void *data)
 {
        int *command = data;
 
-       if (*command & FTRACE_ENABLE_CALLS) {
+       if (*command & FTRACE_ENABLE_CALLS)
                ftrace_replace_code(1);
-               tracing_on = 1;
-       } else if (*command & FTRACE_DISABLE_CALLS) {
+       else if (*command & FTRACE_DISABLE_CALLS)
                ftrace_replace_code(0);
-               tracing_on = 0;
-       }
 
        if (*command & FTRACE_UPDATE_TRACE_FUNC)
                ftrace_update_ftrace_func(ftrace_trace_function);
index 2f76193..b08ee9f 100644 (file)
 #include <linux/list.h>
 #include <linux/fs.h>
 
+#include "trace.h"
+
+/* Global flag to disable all recording to ring buffers */
+static int ring_buffers_off __read_mostly;
+
+/**
+ * tracing_on - enable all tracing buffers
+ *
+ * This function enables all tracing buffers that may have been
+ * disabled with tracing_off.
+ */
+void tracing_on(void)
+{
+       ring_buffers_off = 0;
+}
+
+/**
+ * tracing_off - turn off all tracing buffers
+ *
+ * This function stops all tracing buffers from recording data.
+ * It does not disable any overhead the tracers themselves may
+ * be causing. This function simply causes all recording to
+ * the ring buffers to fail.
+ */
+void tracing_off(void)
+{
+       ring_buffers_off = 1;
+}
+
 /* Up this if you want to test the TIME_EXTENTS and normalization */
 #define DEBUG_SHIFT 0
 
@@ -1133,6 +1162,9 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer,
        struct ring_buffer_event *event;
        int cpu, resched;
 
+       if (ring_buffers_off)
+               return NULL;
+
        if (atomic_read(&buffer->record_disabled))
                return NULL;
 
@@ -1249,6 +1281,9 @@ int ring_buffer_write(struct ring_buffer *buffer,
        int ret = -EBUSY;
        int cpu, resched;
 
+       if (ring_buffers_off)
+               return -EBUSY;
+
        if (atomic_read(&buffer->record_disabled))
                return -EBUSY;
 
@@ -2070,3 +2105,69 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
        return 0;
 }
 
+static ssize_t
+rb_simple_read(struct file *filp, char __user *ubuf,
+              size_t cnt, loff_t *ppos)
+{
+       int *p = filp->private_data;
+       char buf[64];
+       int r;
+
+       /* !ring_buffers_off == tracing_on */
+       r = sprintf(buf, "%d\n", !*p);
+
+       return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t
+rb_simple_write(struct file *filp, const char __user *ubuf,
+               size_t cnt, loff_t *ppos)
+{
+       int *p = filp->private_data;
+       char buf[64];
+       long val;
+       int ret;
+
+       if (cnt >= sizeof(buf))
+               return -EINVAL;
+
+       if (copy_from_user(&buf, ubuf, cnt))
+               return -EFAULT;
+
+       buf[cnt] = 0;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (ret < 0)
+               return ret;
+
+       /* !ring_buffers_off == tracing_on */
+       *p = !val;
+
+       (*ppos)++;
+
+       return cnt;
+}
+
+static struct file_operations rb_simple_fops = {
+       .open           = tracing_open_generic,
+       .read           = rb_simple_read,
+       .write          = rb_simple_write,
+};
+
+
+static __init int rb_init_debugfs(void)
+{
+       struct dentry *d_tracer;
+       struct dentry *entry;
+
+       d_tracer = tracing_init_dentry();
+
+       entry = debugfs_create_file("tracing_on", 0644, d_tracer,
+                                   &ring_buffers_off, &rb_simple_fops);
+       if (!entry)
+               pr_warning("Could not create debugfs 'tracing_on' entry\n");
+
+       return 0;
+}
+
+fs_initcall(rb_init_debugfs);